home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 038a / qbatb503.zip / TOOLBOX.DOC < prev    next >
Text File  |  1991-07-06  |  121KB  |  3,059 lines

  1.  
  2.             Assembly-Language Toolbox for QuickBASIC
  3.             ────────────────────────────────────────
  4.                        By Christy Gemmell
  5.  
  6. The Assembly-Language Toolbox started life, four years ago, as a simple
  7. collection of useful routines for adding zip to my QuickBASIC programs.
  8. They weren't just pretty faces however. In order to qualify, the Toolbox
  9. routines had to work reliably with real-life commercial applications, the
  10. ones on which my living depended. This made for pretty tough testing, but
  11. those which did survive were, in consequence, fast, robust and, above all,
  12. able to do the job. They are, in fact, doing so in Accountants and Stock-
  13. broker's offices, all over my native Great Britain.
  14.  
  15. A colleague uploaded a copy of the Toolbox onto a local BBS (Electronic
  16. Bulletin Board) and suddenly I started getting letters and phone calls
  17. from complete strangers asking for a copy of the latest version. Nearly
  18. everyone who called had suggestions of their own, remarking; "You know, if
  19. only the Toolbox had this, it would be really good...".
  20.  
  21. Wherever practicable, the good ideas (and some were brilliant) were turned
  22. into assembler code and added to the collection. Almost before I realised
  23. what was happening, the Assembly-Language Toolbox was on the Shareware
  24. circuit and being used by programmers in Europe, the USA, Canada,
  25. Australia and Japan. By December 1990 it had gone through four 'official'
  26. releases and a dozen or more unofficial ones.
  27.  
  28. Release Five comes in two flavours; one for QuickBASIC 4 and the other for
  29. Microsoft's BASIC 7 Professional Development System. The QB4 version
  30. covers QuickBASIC 4.0, 4.5 and BASIC 6 while the PDS version is compatible
  31. with BASIC 7, 7.1 and Extended QuickBASIC (QBX). In either version the
  32. routines are provided both as stand-alone libraries and as Quick Libraries
  33. for use in the programming environment.
  34.  
  35. Using the Toolbox is easy. All the routines are written to look like
  36. standard QuickBASIC SUB programs and FUNCTION procedures. All you have to
  37. do is choose the ones you want to use in your current program and paste
  38. the appropriate DECLARE statements (a full set is provided) into the
  39. source code. If you need to output large quantities of text to the screen
  40. at high speed, for example, just copy the following line from TOOLBOX.DEF.
  41.  
  42. DECLARE SUB FastPrint (BYVAL Row%, BYVAL Col%, Text$, BYVAL Attribute%)
  43.  
  44. Then, if you are running in the QuickBASIC environment, you should load
  45. the Quick Library with the command:
  46.  
  47.     QB yourprog.bas /L toolbox.qlb
  48.  
  49. Thereafter you can call FastPrint, exactly as you would any other
  50. QuickBASIC SUB program, for example like this:
  51.  
  52.     FastPrint 25, 34, "Hello World!", 48
  53.  
  54. which will print 'Hello World!' in the middle of the 25th screen row
  55. displaying it in black characters on a cyan background (if you have a
  56. colour monitor). Notice that, since a DECLARE statement has been used, you
  57. don't need to place parentheses around the argument list and that even the
  58. CALL statement is unneccessary. Used in this way, Toolbox routines become
  59. actual extensions to the QuickBASIC language.
  60.  
  61. The same DECLARE statements can still be used when you compile your
  62. programs from the DOS command line. In this case, however, you must link
  63. the compiled program to TOOLBOX.LIB, the stand-alone library, with
  64. something like this:
  65.  
  66.     LINK yourprog,,,toolbox.lib;
  67.  
  68. The QuickBASIC Linker will only extract, from TOOLBOX.LIB, those modules
  69. which are explicitly named by DECLARE statements in the source file. This
  70. ensures that your programs are not burdened with unneccessary code.
  71.  
  72. Toolbox routines do not require the BASIC runtime module to be present.
  73. You can use them to produce completely stand-alone application programs
  74. which can be distributed commercially.
  75.  
  76. As its name implies, the core routines in the Assembly-Language Toolbox
  77. are written in pure Intel 80x86 assembler. Because of this they are small,
  78. efficient and blindingly fast. Moreover, since any internal variables are
  79. stored in a routine's own code segment, your program does not have to
  80. share any of it's precious data space with the library.
  81.  
  82. Christy Gemmell                                                 June 1991
  83.  
  84. ──────────────────────────────────────────────────────────────────────────
  85.  
  86. The ShareWare version of the Assembly-Language Toolbox for QuickBASIC is
  87. provided, free of charge, to any QuickBASIC programmer who can find a use
  88. for it. You are encouraged to copy it, upload it to Electronic Bulletin
  89. Boards or pass it on to friends, provided only that you make no charge for
  90. doing so and that all the files on the disk are preserved intact. You may
  91. freely include Toolbox routines in your own programs, both for private use
  92. and for commercial distribution, without payment to the author.
  93.  
  94. The Professional version of the Toolbox, available to Registered Users,
  95. comes complete with all the source code, object modules for building your
  96. own custom libraries and many additional features. Registration also
  97. entitles you to a free upgrade to Release 6 of the Toolbox, when it
  98. becomes available, and to subsequent releases at a greatly reduced price.
  99. Full Hotline support is also included, at no extra charge.
  100.  
  101. Also available is the Mixed-Language Toolbox for QuickBASIC - a collection
  102. of high-level routines which interface with the Assembly-Language Toolbox
  103. to produce a set of sophisticated mini-applications. The BarMenu and
  104. VerMenu modules, for example, can be used to give your programs a full-
  105. featured point-and-shoot menuing system, similar to the one built into the
  106. QuickBASIC programming environment. Once again, the source code for all
  107. mixed-language routines is provided so that you can tailor them to your
  108. exact requirements.
  109.  
  110. ─────Registration and Support──────────────────────────────────────────────
  111.  
  112. U.K. and Europe:        £30.00 (including postage and packing)
  113.  
  114. Christy Gemmell         Singular Software
  115.                         22 Peake Road, Northfields,
  116.                         Leicester LE4 7DN
  117.                         United Kingdom
  118.                         
  119.                 Tel:    (044)-0533-767960
  120.  
  121. U.S.A. and Canada:      $47.50 (Including shipping)
  122.  
  123. James J. Kreyling       CPC Consulting Company
  124.                         1217 Crescent Dive
  125.                         Smithfield, Va. 23430
  126.                         U.S.A.
  127.  
  128.                 Tel:    (804)-357-7635
  129. or from Club-PC BBS:    (804)-357-0357 (8-N-1)
  130.  
  131. Note:   When ordering the Toolbox please specify if for QuickBASIC 4.5
  132.         or BASIC 7 PDS and the floppy disk format you require.
  133.  
  134. ─────About the author─────────────────────────────────────────────────────
  135.  
  136. Christy Gemmell, the author of this package, is also major author of the
  137. definitive textbook on QuickBASIC programming, the QuickBASIC BIBLE, which
  138. is published by Microsoft Press, in association with the Waite Group, at
  139. £24.95 ($27.95 US) ISBN 1-55615-262-0. Selected as Computer Book of the
  140. Month by Jerry Pournelle in the March 1991 issue of BYTE, its thousand
  141. pages are packed with information, tips and example programs which you
  142. wont find anywhere else.  Look out for it in your local bookstore.
  143.  
  144. The Assembly-Language Toolbox for QuickBASIC is used by thousands of
  145. programmers in Great Britain, Europe, the USA and Canada, Australasia and
  146. Japan, to build fast and powerful QuickBASIC programs. It has been shown
  147. at COMDEX and was featured in the November 1990 issue of BYTE magazine.
  148.  
  149. ───────────────────────────────────────────────────────────────────────
  150.  
  151.                 TOOLBOX FUNCTIONS AND PROCEDURES
  152.  
  153. This is a full, alphabetical, listing of the routines in the Assembly
  154. Language Toolbox which can be called directly by QuickBASIC programs>
  155.  
  156.  
  157. ATTRIB
  158.  
  159. This function returns the directory attributes of the specified file.
  160.  
  161. DECLARE FUNCTION Attrib% (FileSpec$)
  162.  
  163. FileSpec$ is the name of the file whose directory entry is to be tested.
  164. You should include the full pathname (including drive letter if necessary)
  165. if the file is not in the current directory.
  166.  
  167. The returned attribute value is bit-encoded as follows:
  168.  
  169.    Bit     Meaning (if set)
  170. ─────────────────────────────────────────────────────
  171.     0      Read-only     (file is Read/Write if zero)
  172.     1      Hidden
  173.     2      System
  174.     3      Volume label
  175.     4      Subdirectory
  176.     5      Archive
  177.     6      Not used
  178.     7      Shareable     (Novell Networks only)
  179. ─────────────────────────────────────────────────────
  180.  
  181. The ToolBox procedures; HIDE, SECURE and SHARE (see below) can be used to
  182. modify the attributes of a file.
  183.  
  184.  
  185. ATTRIBUTE
  186.  
  187. Converts standard QuickBASIC foreground and background COLOR values into
  188. their equivalent display attribute number.
  189.  
  190. DECLARE FUNCTION Attribute% (BYVAL Fore%, BYVAL Back%)
  191.  
  192. The Assembly-Language Toolbox provides several routines which allow  your
  193. QuickBASIC programs to write text directly to the display with an
  194. attribute which you supply. For an explanation of display attributes, see
  195. the topic file COLOURS.HLP supplied with the Assembly-Language Toolbox
  196. demonstration program.
  197.  
  198.  
  199. BACKFILL
  200.  
  201. This procedure changes the display attributes of the characters contained
  202. within the screen rectangle you specify, without overwriting the text
  203. itself.
  204.  
  205. DECLARE SUB BackFill (BYVAL R%, BYVAL C%, BYVAL H%, BYVAL W%, BYVAL A%)
  206.  
  207. R% = Top-left row of the rectangle to be coloured.
  208. C% = Top-left column of the rectangle.
  209. H% = Height of the rectangle in rows.
  210. W% = Width of the rectangle in columns.
  211. A% = Display attribute to use for colouring.
  212.  
  213.  
  214. CAPSLOCK
  215.  
  216. Toggles CAPS LOCK on or off or, alternatively, reads the current CAPS LOCK
  217. key setting.
  218.  
  219. DECLARE FUNCTION CapsLock% (BYVAL Switch%)
  220.  
  221. Switch% = 0  Turns CAPS LOCK off
  222.         = 1  Turns CAPS LOCK on
  223.  
  224. Any other value just returns the current CAPS status as a logical value
  225. where -1 (TRUE) means that CAPS LOCK is on and 0 (FALSE) means that CAPS
  226. LOCK is off.
  227.  
  228.  
  229. CGACOPY
  230.  
  231. Copies a CGA screen to or from a user-supplied string.
  232.  
  233. DECLARE SUB CgaCopy (BYVAL Switch%, Buffer$)
  234.  
  235. SWITCH%     Direction of copy   0 = copy screen to string
  236.                                 1 = copy string to screen
  237.  
  238. BUFFER$     String variable to hold the screen image, must be at least
  239.             16384 characters long or the call will fail. 
  240.  
  241. Note:       If you are using QuickBASIC 4 or 4.5, do not pass a fixed-
  242.             length string to this routine. Only variable-length strings
  243.             will work safely.
  244.  
  245. The QuickBASIC PCOPY statement is very useful for storing screen pages in
  246. memory, so that they can be kept out of sight until needed. Unfortunately
  247. it only works in text modes or, on computers with EGA or VGA video cards,
  248. in SCREEN modes 7 to 12. This routine, on the other hand, works only in
  249. the CGA display modes (SCREENs 1 and 2), it provides a useful alternative
  250. to the PCOPY statement for use with medium-resolution screens.
  251.  
  252. See also MCGACOPY for a version that can be used with SCREEN 13 displays.
  253.  
  254.  
  255. CGASCROLL
  256.  
  257. Scrolls a rectangular portion of a SCREEN 1 (320 x 200 4-colour) display
  258. four pixels to the left or to the right, wrapping the pixels which are 
  259. scrolled out at the end round to the beginning again.
  260.  
  261. DECLARE SUB CgaScroll (BYVAL xLoc%, BYVAL yLoc%, BYVAL xPixels%,_
  262.                        BYVAL yPixels%, BYVAL Direction%)                 
  263.  
  264. XLOC%       The horizontal (X) co-ordinate of the top-left corner of
  265.             the rectangle to be scrolled.
  266.  
  267. YLOC%       The vertical (Y) co-ordinate of the top-left corner of
  268.             the rectangle to be scrolled.
  269.  
  270. XPIXELS%    The width (in pixels) of the rectangle to be scrolled.
  271.  
  272. YPIXELS%    The height (in pixels) of the rectangle to be scrolled.
  273.  
  274. DIRECTION%  The direction in which the rectangle contents are to be
  275.             scrolled (0 = Left, 1 = Right).
  276.  
  277. Co-ordinates are in the ranges:  X >= 0 <= 319, Y >= 0 <= 199
  278.  
  279. X co-ordinates are aligned to the nearest byte (1 byte = 4 pixels).
  280.  
  281.  
  282. CGATEXT
  283.  
  284. Writes characters to the screen in the 320 x 200 4-colour graphics mode.
  285.  
  286. DECLARE SUB CgaText (BYVAL xLoc%, BYVAL yLoc%, Text$,_
  287.                      BYVAL Attr%, BYVAL Scale%)
  288.  
  289. This routine provides a convenient way of displaying text in SCREEN 1
  290. without having to bother about loading external font files. It uses the
  291. standard ROM-BIOS character definition tables built into your display
  292. adaptor, but allows you to scale them up to eight times normal size and to
  293. specify any combination of foreground and background colours.
  294.  
  295. XLOC%       The horizontal co-ordinate of the top left hand pixel
  296.             from which the text will begin (0 - 319)
  297.  
  298. YLOC%       The vertical co-ordinate of the top left hand pixel
  299.             from which the text will begin (0 - 199)
  300.  
  301. TEXT$       The string of text to be displayed (up to 63 characters).
  302.  
  303. ATTR%       The colour (or display attribute in monochrome modes) to
  304.             be given to the text. This is calculated by the formula:
  305.  
  306.             Colour% = (Background% * 256) + Foreground%
  307.  
  308.             Foreground and Background values are in the range 0 - 3
  309.  
  310. SCALE%      The character size of the text to be displayed. This ranges
  311.             from 1 to 8, where 1 is standard 40-column text and where 8
  312.             multiplies the character size by eight on both the horizontal
  313.             and vertical axes.
  314.  
  315. CGATEXT can handle both byte-aligned and non byte-aligned characters. The
  316. x, y co-ordinates you supply do not need to correspond to a row, column
  317. character cell in SCREEN 0, the alphanumeric mode. The complete ASCII set
  318. is supported, but to display foreign symbols and box-drawing characters on
  319. a CGA adaptor you must have the DOS GRAFTABL utility loaded.
  320.  
  321. Since CGATEXT does not support clipping, to ensure a clean display you
  322. must ensure that the text to be output fits within the current screen
  323. boundaries.
  324.  
  325. See also VGATEXT for displaying characters in SCREENs 7-12 and MCGATEXT
  326. for displaying characters in SCREEN 13.
  327.  
  328.  
  329. CIPHER
  330.  
  331. This routine requires that you supply two strings of characters. The first
  332. is the text to be encrypted, and the second is one or more keywords which
  333. are used to encipher the text. Thereafter, the text cannot be decrypted
  334. until you supply the same key string again.
  335.  
  336. DECLARE SUB Cipher (Text$, KeyWord$)
  337.  
  338. The encryption algorithm XORs (eXclusive ORs) the key string with string
  339. to be encrypted. This allows you to reverse the procedure and decrypt the
  340. text, simply by calling the routine a second time.
  341.  
  342. See the source code for DEMON.BAS, the ToolBox demonstration program, for
  343. an example using CIPHER.
  344.  
  345.  
  346. CLEAREND
  347.  
  348. Blank spaces of the display attribute specified are printed, starting at
  349. the current cursor position and continuing to the end of the line or,
  350. optionally, to the end of the screen.
  351.  
  352. DECLARE SUB ClearEnd (BYVAL Switch%, BYVAL Attr%)
  353.  
  354. Switch%   0 = clear to the end of the line.
  355.           1 = clear to the end of the screen.
  356.  
  357. Attr%     display attribute (1 - 255). If zero is specified then the
  358.           attribute of the character under the cursor is used.
  359.  
  360. Example:  ClearEnd 1, 0
  361.  
  362. Clears from the current cursor position to the bottom of the screen. The
  363. area cleared takes the background colour of the character under the
  364. cursor. The cursor, itself, is not updated.
  365.  
  366.  
  367. CPU
  368.  
  369. This function checks to see what type of microprocessor is installed in
  370. the computer in which the current program is running.
  371.  
  372. No calling parameters are required.
  373.  
  374. DECLARE FUNCTION Cpu% ()
  375.  
  376. The following processors can be identified by their return values :
  377.  
  378.  86 = Intel 8086          88 = Intel 8088         188 = Intel 80188        
  379. 186 = Intel 80186        286 = Intel 80286        386 = Intel 80386
  380. -86 = Intel 80C86        -88 = Intel 80C88         20 = NEC   V20
  381.  30 = NEC   V30
  382.  
  383. 486 = Intel 80486  included but not yet tested (lend us yours?).
  384.  
  385. This function is provided mainly for interest, although it can be used as
  386. an indication of how long a particular task will take to run. All of the
  387. Toolbox routines, in fact, are processor-independent and can be used on
  388. all types of IBM-PC, AT, PS/2 and compatible machines
  389.  
  390.  
  391. CURTAINS
  392.  
  393. This routine clears the display screen to the background colour specified
  394. by Attribute%. It differs from CLS in that the blanked-out area expands
  395. from a series of columns, giving the effect of a set of louvered blinds or
  396. curtains being closed. The Speed% parameter controls how quickly the
  397. routine runs, larger values making the curtains close more slowly.
  398.  
  399. DECLARE SUB Curtains (BYVAL Speed%, BYVAL Attribute%)
  400.  
  401. Try this example for a fancy effect:
  402.  
  403. FOR I% = 255 TO 0 STEP -16: Curtains 40, I%: NEXT
  404.  
  405. This procedure calls the DELAY routine (see below). This ensures that the
  406. speed value you specify will produce the same result on computers with any
  407. type of processor or clock speed.
  408.  
  409.  
  410. DAYNUMBER
  411.  
  412. Convert a date in the form DD/MM/YYYY to a long integer. The values
  413. returned are valid with dates in the range 1/3/1900 - 31/12/2099.
  414.  
  415. DECLARE FUNCTION DayNumber& (BYVAL Day%, BYVAL Month%, BYVAL Year%)
  416.  
  417. See the INTERVAL function (below) for a method of calculating the number
  418. of days between two Julian dates.
  419.  
  420.  
  421. DELAY
  422.  
  423. This procedure is like the QuickBASIC SLEEP statement, except that it
  424. allows you to specify an interval in milliseconds instead of just whole
  425. seconds. The delay will be exactly the same on a 4.77 MHz original PC as
  426. it would be on the latest 33-MHz 80486 machine.
  427.  
  428. DECLARE SUB Delay (BYVAL MilliSeconds%)
  429.  
  430. See the PAUSE routine (below) for a similar procedure which allows you to
  431. specify a delay in PC clock ticks.
  432.  
  433.  
  434. DISABLEPRTSC
  435.  
  436. This routine simply sets the Print Screen Busy flag at low-memory address
  437. 0040:0100 (Hex) so that any requests for the screen to be printed are
  438. ignored. Use this to prevent a careless operator from hanging-up the
  439. program by pressing <Prt Scrn> when the printer is off-line.
  440.  
  441. No calling parameters are required.
  442.  
  443. DECLARE SUB DisablePrtSc ()
  444.  
  445. Don't forget to use ENABLEPRTSC (see below) to re-enable this key
  446. otherwise it will remain disabled even after your program ends.
  447.  
  448.  
  449. DISKREADY
  450.  
  451. Tests if there is readable media in the floppy diskette drive specified. 
  452.  
  453. DRIVE% is the number of the diskette drive to be tested and is a value
  454. between 0 and 3, where 0 = A:, 1 = B:, etc.
  455.  
  456. DECLARE FUNCTION DiskReady% (BYVAL Drive%)
  457.  
  458. This function returns -1 (logical TRUE) if a readable diskette is in the
  459. drive, and zero (logical FALSE) if unable to read from the drive.
  460.  
  461. Note:       DISKREADY only tests if the drive can be read from. It will
  462.             not detect if the diskette in the drive is write-protected.
  463.  
  464.  
  465. DISPLAYMODE
  466.  
  467. Reads the current video display mode using the IBM ROM-BIOS numbering
  468. system.
  469.  
  470. DECLARE FUNCTION DisplayMode% ()
  471.  
  472. No calling parameters are required. Depending on the type of display
  473. adaptor installed, the function may return one of the following values:
  474.  
  475. Mode    Resolution      Mode     Colours    Remarks
  476. ─────────────────────────────────────────────────────────────────────
  477.   0     40 x 25         text        16      No colour burst
  478.   1     40 x 25         text        16      
  479.   2     80 x 25         text        16      No colour burst
  480.   3     80 x 25         text        16
  481.   4     320 x 200       graphics     4
  482.   5     320 x 200       graphics     4      No colour burst
  483.   6     640 x 200       graphics     2
  484.   7     80 x 25         text         2      Monochrome display only  
  485.   8     160 x 200       graphics    16      PCjr & Tandy 1000 only  
  486.   9     320 x 200       graphics    16      PCjr & Tandy 1000 only
  487.  10     640 x 200       graphics     4      PCjr & Tandy 1000 only
  488.  13     320 x 200       graphics    16      EGA & VGA
  489.  14     640 x 200       graphics    16      EGA & VGA
  490.  15     640 x 350       graphics     2      Monochrome EGA & VGA
  491.  16     640 x 350       graphics    16      EGA & VGA
  492.  17     640 x 480       graphics     2      VGA only
  493.  18     640 x 480       graphics    16      VGA only
  494.  19     320 x 200       graphics   256      VGA & MCGA      
  495. ─────────────────────────────────────────────────────────────────────
  496.  
  497. The SCREENMODE function (see below) can be used to return the equivalent
  498. QuickBASIC SCREEN number.
  499.  
  500.  
  501. DISPLAYPAGE
  502.  
  503. All video cards except the Monochrome Display Adaptor (MDA) are capable of
  504. switching between two or more pages of display memory. This function
  505. returns the number of the active video page, use the QuickBASIC SCREEN
  506. statement to select the page you require.
  507.  
  508. No calling parameters are required.
  509.  
  510. DECLARE FUNCTION DisplayPage% ()
  511.  
  512. The page number returned can be a value between 0 and 7, depending upon
  513. the current video mode and the amount of display memory installed.
  514.  
  515. Note:       all Toolbox routines which write directly to the screen will
  516.             automatically detect and send their output to the currently
  517.             active display page.
  518.  
  519.  
  520. DWPRINT
  521.  
  522. Sends the text supplied, to the printer, as a string of double-width
  523. characters. Output begins at the current print position and can,
  524. optionally, append a carriage-return/linefeed to take the print head to
  525. the beginning of a new line when finished.
  526.  
  527. DECLARE SUB DwPrint (BYVAL Printer%, Buffer$, BYVAL NewLine%)
  528.  
  529. Arguments:  Printer%    the parallel port output is to be sent to
  530.                         (1 = LPT1:, 2 = LPT2:, etc.).
  531.             Buffer$     the string of text to be printed.
  532.             NewLine%    set this to a non-zero value if you want 
  533.                         to move to a new line after printing.
  534.  
  535. The routine restores the previous print style or font before it returns
  536. and does not effect subsequent output to the printer, using the QuickBASIC
  537. LPRINT or PRINT # statements.
  538.  
  539. Note:       The version of this routine stored in the Toolbox
  540.             library is for EPSON compatible printers. If you have
  541.             an IBM graphics printer or ProPrinter, then you should
  542.             rebuild your libraries, using either the PRINTIBM.OBJ
  543.             or PRINTPRO.OBJ object module in place of PRINTEPS.OBJ.
  544.  
  545.  
  546. EMPRINT
  547.  
  548. Sends the text supplied, to the printer, as a string of emphasised
  549. characters. Output begins at the current print position and can,
  550. optionally, append a carriage-return/linefeed to take the print head to
  551. the beginning of a new line when finished.
  552.  
  553. DECLARE SUB EmPrint (BYVAL Printer%, Buffer$, BYVAL NewLine%)
  554.  
  555. Arguments:  Printer%    the parallel port output is to be sent to
  556.                         (1 = LPT1:, 2 = LPT2:, etc.).
  557.             Buffer$     the string of text to be printed.
  558.             NewLine%    set this to a non-zero value if you want 
  559.                         to move to a new line after printing.
  560.  
  561. The routine restores the previous print style or font before it returns
  562. and does not effect subsequent output to the printer, using the QuickBASIC
  563. LPRINT or PRINT # statements.
  564.  
  565. Note:       The version of this routine stored in the Toolbox
  566.             library is for EPSON compatible printers. If you have
  567.             an IBM graphics printer or ProPrinter, then you should
  568.             rebuild your libraries, using either the PRINTIBM.OBJ
  569.             or PRINTPRO.OBJ object module in place of PRINTEPS.OBJ.
  570.  
  571.  
  572. EMSERROR
  573.  
  574. Returns the code number of the last error which occurred during a
  575. call to the Expanded Memory Manager. If zero is returned, then no
  576. errors have occurred.
  577.  
  578. No calling parameters are required.
  579.  
  580. DECLARE FUNCTION EmsError% ()
  581.  
  582. Here is a list of possible error codes and their meanings:
  583.  
  584. 128  Internal error in EMM software     146  Source and target overlap
  585. 129  Malfunction in EMS hardware        147  Illegal region length
  586. 130  Memory manager busy                148  Region overlap
  587. 131  Invalid handle                     149  Offset outside logical page
  588. 132  Function not defined               150  Region length > 1MB
  589. 133  No more handles available          151  Cannot exchange overlap
  590. 134  Error in mapping context           152  Memory types undefined
  591. 135  Not enough pages exist             153  Not used
  592. 136  Not enough pages available         154  ARS not supported
  593. 137  Cannot allocate zero pages         155  ARS currently allocated
  594. 138  Page not allocated to handle       156  ARS not zero
  595. 139  Illegal physical page number       157  ARS not allocated
  596. 140  Save state area full               158  DMA channels not supported
  597. 141  Save of mapping context failed     159  Illegal DMA channel
  598. 142  Restore of mapping context failed  160  No handle for this name
  599. 143  Subfunction parameter not defined  161  Name already exists
  600. 144  Attribute type not defined         162  Memory address wrap
  601. 145  Feature not supported              163  Invalid pointer
  602.  
  603. 250  EMM not installed*                 251  LIM 4.0 required*
  604.  
  605. *    Toolbox error codes.
  606.  
  607. The descriptions are, of necessity, abbreviated. For more information 
  608. consult your EMS hardware manual or see:
  609.  
  610. Advanced MS-DOS Programming     by David Duncan     Microsoft Press
  611.  
  612.  
  613. EMSFRAME
  614.  
  615. Returns the segment address of the EMS page frame.
  616.  
  617. No calling parameters are required.
  618.  
  619. DECLARE FUNCTION EmsFrame% ()
  620.  
  621. The Page Frame is the area of conventional memory into which logical
  622. expanded memory pages are mapped. Under LIM 3.2 it is a contiguous
  623. block of 64RAM, divided into four 16K physical pages, located some-
  624. where between segments A000 and F000 Hex, but LIM 4.0 allows you to
  625. reserve additional 16K pages, wherever available memory exists. In
  626. either system you can rely on 4 consecutive 16K pages and this
  627. function returns a pointer to the first of them.
  628.  
  629.  
  630. EMSGET
  631.  
  632. Copies up to 64KB of data from expanded memory, starting at the
  633. logical page supplied, to an address in conventional memory.
  634.  
  635. DECLARE SUB EmsGet (BYVAL Segment%, BYVAL Offset%, BYVAL Length%,_
  636.                     BYVAL Page%, BYVAL Handle%, Done%)
  637.  
  638. Arguments:  Segment%  = segment address of target block to which
  639.                         data should be copied.
  640.             Offset%   = offset address, within target segment, to
  641.                         which data should be copied.
  642.             Length%   = length, in bytes (up to 64KB), of data to
  643.                         be copied. 
  644.             Page%     = logical EMS page holding the beginning of
  645.                         the data. If the block of data is bigger
  646.                         than 16KB, then copying will continue from
  647.                         subsequent pages until all the data has 
  648.                         been moved.
  649.             Handle%   = the EMS handle to which the page(s) have
  650.                         been allocated. This should be obtained by
  651.                         a previous call to the EMSRESERVE procedure
  652.                         (see below).
  653.             Done%     = a flag to hold the result of the operation.
  654.                         If the data was copied successfully, it is
  655.                         set to -1 (logical TRUE) on return. If zero
  656.                         (logical FALSE) is returned, the data was
  657.                         not copied successfully. In this case, you
  658.                         should make a call to the EMSERROR function
  659.                         to find out why.
  660.  
  661. If the target structure, to which the data is to be copied, is an
  662. array, you should specify its address by supplying the VARSEG and
  663. VARPTR of the first element. Be sure, however, that you do not copy
  664. a block of data bigger than the array size, otherwise you may 
  665. overwrite other variables, probably with disastrous results. 
  666.  
  667. See the EMSPUT procedure (below) for a means of copying data into
  668. logical expanded memory pages.
  669.  
  670.  
  671. EMSMAP
  672.  
  673. Map a logical expanded memory page to a physical page in the EMS
  674. Page Frame, making it accessible to your program.
  675.  
  676. DECLARE SUB EmsMap (BYVAL Handle%, Physical%, Logical%)
  677.  
  678. Arguments:  Handle%   = the EMS handle to which the logical page has
  679.                         been allocated. This will have been obtained
  680.                         by a previous call to the EMSRESERVE routine
  681.                         (see below).
  682.             Physical% = the number of the physical page to map
  683.                         (in the range 1 to 4).
  684.             Logical%  = the number of the logical page to be mapped
  685.                         (in the range from 1 to the number of pages
  686.                         allocated to Handle%).
  687.  
  688. For most applications, the EMSGET and EMSPUT procedures will be more
  689. useful, since they perform all the necessary mapping for you while
  690. moving data to and from expanded memory. If, however, you need to
  691. manipulate small quantities of data in expanded memory, use this
  692. routine to switch the relevant page into conventional memory, and
  693. the FARPEEK and FARPOKE utilities (see below) to examine or change
  694. the data itself.
  695.  
  696.  
  697. EMSOWNED
  698.  
  699. Returns the number of logical pages of EMS memory that have been
  700. allocated to the handle specified.
  701.  
  702. DECLARE FUNCTION EmsOwned% (BYVAL Handle%)
  703.  
  704.  
  705. EMSPAGES
  706.  
  707. Returns either the total number of EMS pages in the system, or the
  708. total number of free (unallocated) pages.
  709.  
  710. DECLARE FUNCTION EmsPages% (BYVAL Switch%)
  711.  
  712. Argument:   Switch% = 1  return number of unallocated pages.
  713.                       0  return total number of pages in system.
  714.  
  715.  
  716. EMSPRESENT
  717.  
  718. Tests whether the Expanded Memory System driver has been installed
  719.  
  720. No calling parameters are required.
  721.  
  722. DECLARE FUNCTION EmsPresent% ()
  723.  
  724. Returns:    -1  (logical TRUE) if EMS driver is installed.
  725.              0  (logical FALSE) if EMS driver is not installed.
  726.  
  727. Note:       This function just checks that the EMS driver is in
  728.             memory and that the EMS interrupt vector is directed
  729.             to it, it does not test if the driver is active. Use
  730.             the EMSVERSION function (see below) to test this. If
  731.             the driver responds to that function, it can be safely
  732.             assumed to be active.
  733.  
  734.  
  735. EMSPUT
  736.  
  737. Copies up to 64KB of data to expanded memory, starting at the
  738. logical page supplied, from an address in conventional memory.
  739.  
  740. DECLARE SUB EmsPut (BYVAL Segment%, BYVAL Offset%, BYVAL Length%,_
  741.                     BYVAL Page%, BYVAL Handle%, Done%)
  742.  
  743. Arguments:  Segment%  = segment address of source block from which
  744.                         data is to be copied.
  745.             Offset%   = offset address, within target segment, from
  746.                         which data is to be be copied.
  747.             Length%   = length, in bytes (up to 64KB), of data to
  748.                         be copied to expanded memory. 
  749.             Page%     = logical EMS page to hold the beginning of
  750.                         the data. If the block of data is bigger
  751.                         than 16KB, then copying will continue onto
  752.                         subsequent pages until all the data has 
  753.                         been moved.
  754.             Handle%   = the EMS handle to which the page(s) have
  755.                         been allocated. This should be obtained by
  756.                         a previous call to the EMSRESERVE procedure
  757.                         (see below).
  758.             Done%     = a flag to hold the result of the operation.
  759.                         If the data is copied successfully, it will
  760.                         be set to -1 (logical TRUE) on return. If
  761.                         zero (logical FALSE) is returned, the data
  762.                         was not copied successfully. In this case,
  763.                         you should make a call to the EMSERROR
  764.                         function to find out why.
  765.  
  766. If the source structure, from which the data is to be copied, is an
  767. array, you should specify its address by supplying the VARSEG and
  768. VARPTR of the first element. You can also copy data from absolute
  769. addresses in memory to EMS, to copy the contents of the text screen,
  770. for example, to EMS logical page 2, use the command:
  771.  
  772.     EmsPut &HB800, 0, 4000, 3, Handle%, Done%
  773.  
  774. This assumes that your computer has a colour monitor. If you have a
  775. monochrome display, substitute &HB000 for the segment address.
  776.  
  777. See the EMSGET procedure (above) for a means of retrieving data from
  778. extended memory.
  779.  
  780.  
  781. EMSRELEASE
  782.  
  783. Free-up all the pages previously allocated to this handle, and make
  784. them available to other processes.
  785.  
  786. DECLARE SUB EmsRelease (BYVAL Handle%)
  787.  
  788. You should release all the EMS pages which have been allocated to
  789. handles owned by your program, before the program terminates. If
  790. this is not done, these pages will not be available to subsequent
  791. programs which may start up and will remain locked until the system
  792. is rebooted.
  793.  
  794.  
  795. EMSREQUEST
  796.  
  797. Asks for one or more logical pages of expanded memory to be made
  798. available to your program.
  799.  
  800. DECLARE SUB EmsRequest (BYVAL Pages%, Handle%)
  801.  
  802. Arguments:  Pages%  = number of EMS pages to reserve.
  803.  
  804.             Handle% = if successful, this variable will hold the
  805.                       number of the EMS handle which controls the
  806.                       allocated pages. If unsuccessful, Handle%
  807.                       will be set to zero on return, in which case
  808.                       you should call the EMSERROR function (above)
  809.                       to see what went wrong.
  810.  
  811. You must use this handle in all subsequent calls to the Expanded
  812. Memory Manager which refer to these particular pages.
  813.  
  814. Before calling this procedure, it is a good idea to make a call to
  815. the EMSPAGES function (see above) to see how many pages are free.
  816.  
  817.  
  818. EMSRESIZE
  819.  
  820. Changes the number of pages allocated to an EMS handle.
  821.  
  822. DECLARE SUB EmsReSize (BYVAL Handle%, Pages%)
  823.  
  824. Arguments:  Handle% = a valid EMS handle to which logical expanded
  825.                       memory pages have already been allocated.
  826.  
  827.             Pages%  = the new number of pages to be allocated to
  828.                       this handle.
  829.  
  830. On return, Pages% will hold the actual number of pages that are
  831. now allocated to the handle. If this is different from the number
  832. of pages requested, then an error has occurred and you should call
  833. the EMSERROR function (see above) to check what happened.
  834.  
  835. You can request a number of pages less than or greater than the
  836. number previously allocated to the handle.
  837.  
  838. Note:       This facility is only available with LIM 4.0 EMS and
  839.             above.
  840.  
  841.  
  842. EMSVERSION
  843.  
  844. Returns the LIM version number of the Expanded Memory Manager.
  845.  
  846. No calling parameters are required.
  847.  
  848. DECLARE FUNCTION EmsVersion% ()
  849.  
  850. The number returned is a decimal integer where 32 represents LIM 3.2
  851. and 40 represents LIM 4.0. If zero is returned, then an error has
  852. occurred and you should call the EMSERROR function (see above) to
  853. find out what happened. Use the EMSPRESENT function (also above) to
  854. test that the EMM driver has, in fact, been installed.
  855.  
  856.  
  857. ENABLEPRTSC
  858.  
  859. This routine clears the Busy flag at low-memory address 0040:0100 (Hex) so
  860. that print-screen requests can be executed. Use it to cancel the effect of
  861. the DISABLEPRTSC procedure (above).
  862.  
  863. No calling parameters are required.
  864.  
  865. DECLARE SUB EnablePrtSc ()
  866.  
  867.  
  868. ENPRINT
  869.  
  870. Sends the text supplied, to the printer, as a string of enhanced
  871. characters. Output begins at the current print position and can,
  872. optionally, append a carriage-return/linefeed to take the print head to
  873. the beginning of a new line when finished.
  874.  
  875. DECLARE SUB EnPrint (BYVAL Printer%, Buffer$, BYVAL NewLine%)
  876.  
  877. Arguments:  Printer%    the parallel port output is to be sent to
  878.                         (1 = LPT1:, 2 = LPT2:, etc.).
  879.             Buffer$     the string of text to be printed.
  880.             NewLine%    set this to a non-zero value if you want 
  881.                         to move to a new line after printing.
  882.  
  883. The routine restores the previous print style or font before it returns
  884. and does not effect subsequent output to the printer, using the QuickBASIC
  885. LPRINT or PRINT # statements.
  886.  
  887. Note:       The version of this routine stored in the Toolbox
  888.             library is for EPSON compatible printers. If you have
  889.             an IBM graphics printer or ProPrinter, then you should
  890.             rebuild your libraries, using either the PRINTIBM.OBJ
  891.             or PRINTPRO.OBJ object module in place of PRINTEPS.OBJ.
  892.  
  893.  
  894. EXPLODE
  895.  
  896. Clear a screen rectangle explosively. This as an alternative to the
  897. SCROLL routine listed below.
  898.  
  899. DECLARE SUB Explode (BYVAL Y1%, BYVAL X1%, BYVAL Y2%, BYVAL X2%,_
  900.                      BYVAL Attribute%, BYVAL Speed%)
  901.  
  902. Arguments:  Y1%         =  Upper-left row of rectangle to be cleared
  903.             X1%         =  Upper-left column of rectangle
  904.             Y2%         =  Lower-right row of rectangle
  905.             X2%         =  Lower-right column of rectangle
  906.             Attribute%  =  Display attribute or colour that rectangle
  907.                            should be cleared to 
  908.             Speed%      =  Speed (in milliseconds) of explosion.
  909.  
  910. The panel is cleared, starting at the centre point, and progressively
  911. moving outwards until the defined borders are reached. This gives the
  912. impression of the clear area exploding onto the screen.
  913.  
  914. This routine is called, internally, by the POPUP window function (see
  915. below) whenever Zoom is specified.
  916.  
  917.  
  918. FARPEEK
  919.  
  920. Reads a byte of data from anywhere in conventional memory.
  921.  
  922. DECLARE FUNCTION FarPeek% (BYVAL Segment&, BYVAL Offset&)
  923.  
  924. Arguments:  Segment&  = address of memory segment containing the byte
  925.                         to be read.
  926.             Offset&   = offset address, within the segment of the 
  927.                         byte to be read.
  928.  
  929. Returns:    The contents of the byte specified as an integer value
  930.             in the range 0 to 255.
  931.  
  932. Note:       parameters are passed as LONG integers to save you the
  933.             hassle of having to convert argument values over 32767
  934.             to negative signed integers. Do not use values greater
  935.             than 65535, however, or the most significant word will
  936.             be ignored and the address converted to Modulus 65536.
  937.  
  938. Using QuickBASIC's PEEK function to examine data which lies outside
  939. of DGROUP is a pain. You also have to use DEF SEG to set the segment
  940. required and then to reset it afterwards. This function allows you to
  941. read bytes, directly, from anywhere in the 1 megabyte of addressable
  942. RAM space your computer contains.
  943.  
  944. The FARPOKE procedure (below) complements FARPEEK by allowing you to
  945. write a byte of data anywhere in the 1MB addressable PC workspace.
  946.  
  947. See also PEEKWORD and POKEWORD which allow you to read from and write
  948. to memory, two bytes at a time.
  949.  
  950. Note:       If you have an Intel 286, 386 or 486-based computer with
  951.             the Microsoft HIMEM.SYS driver loaded, you can even use
  952.             FARPEEK to read from the first 64KB of Extended Memory.
  953.             Setting the segment to &HFFFF and an offset in the range
  954.             &H10 to &HFFFF allows you access up to 65520 bytes of
  955.             memory ABOVE the normal 1MB limit.
  956.  
  957.  
  958. FARPOKE
  959.  
  960. Writes a byte of data to anywhere in conventional memory.
  961.  
  962. DECLARE SUB FarPoke (BYVAL Segment&, BYVAL Offset&, BYVAL Byte%)
  963.  
  964. Arguments:  Segment&  = address of memory segment containing the byte
  965.                         to be written to
  966.             Offset&   = offset address, within the segment of the 
  967.                         byte to be written.
  968.             Byte%     = the value (0 to 255) to be written to the
  969.                         specified byte.
  970.  
  971. Note:       addresses are passed as LONG integers to save you the
  972.             hassle of having to convert argument values over 32767
  973.             to negative signed integers. Do not use values greater
  974.             than 65535, however, or the most significant word will
  975.             be ignored and the address converted to Modulus 65536.
  976.  
  977. Using QuickBASIC's POKE function to write to memory which is outside
  978. of DGROUP is a pain. You also have to use DEF SEG to set the segment
  979. you want and then to set it back again afterwards. This function lets
  980. you write bytes, directly, anywhere in the 1 megabyte of addressable
  981. RAM space your computer contains.
  982.  
  983. The FARPEEK procedure (above) complements FARPOKE by allowing you to
  984. read a byte of data from anywhere in the 1MB of addressable memory.
  985.  
  986. See also PEEKWORD and POKEWORD which allow you to read from and write
  987. to memory, two bytes at a time.
  988.  
  989.  
  990. FASTPRINT
  991.  
  992. This procedure can be used to display a string of text directly to video
  993. memory. It is much  faster than the normal DOS services and does not
  994. update the cursor.
  995.  
  996. DECLARE SUB FastPrint (BYVAL Row%, BYVAL Col%, Message$, BYVAL Attr%)
  997.  
  998. Row%        is the row where printing is to start.
  999. Col%        is the column where printing is to start.
  1000. Message$    is the string of text to be printed.
  1001. Attr%       is the video attribute given to the text.
  1002.  
  1003. Row% and Col% follow the QuickBASIC convention of numbering screen rows
  1004. and columns with Row = 1, Column = 1 being at the top-left corner of the
  1005. display. The maximum value for Row% depends on the capabilities of the
  1006. video adaptor installed and is determined by the last WIDTH statement.
  1007. Normally it is 25 but may extend to 43 (EGA) or even 50 rows (VGA).
  1008. Maximum columns may be either 40 or 80 (the default).
  1009.  
  1010. If multiple screen pages are being used, FASTPRINT will correctly identify
  1011. the active one and output to the proper video address.
  1012.  
  1013.  
  1014. FILEDATE
  1015.  
  1016. Gets or sets the date and time of the specified file as is displayed in
  1017. directory listings.
  1018.  
  1019. DECLARE SUB FileDate (BYVAL Switch%, DateTime$, FileSpec$)
  1020.  
  1021. Switch%     if set to a value of 1, changes the date and time of the file
  1022.             to the parameters specified in DateTime$. Any other value
  1023.             returns the date and time that the file was last written to
  1024.             in DateTime$
  1025.  
  1026. DateTime$   A string of at least 17 characters in length. If setting the
  1027.             date and time of a file, this must be written in a standard
  1028.             UK date/time format, ie:
  1029.  
  1030.             "DD/MM/YY HH:MM:SS"
  1031.  
  1032.             If you are reading the date and time, it is not necessary to
  1033.             pre-format the string, as the function will do it for you. The
  1034.             string must be of sufficient length to hold the returned date
  1035.             and time, however, or the procedure will fail.
  1036.  
  1037. FileSpec$   A string holding the pathname of the file to be examined or
  1038.             changed. It can include the drive letter and directory path
  1039.             were appropriate, but must be an explicit pathname. Wildcard
  1040.             characters are not allowed. Maximum length is 64 characters.
  1041.  
  1042. The procedure will fail if the file does not exist or is not on the path
  1043. specified. Also, since the file is actually opened by the procedure, there
  1044. must be at least one free DOS file handle available when you call it.
  1045.  
  1046. You cannot change the date and time of a file which has been flagged as
  1047. readonly or, on a network, is owned by another program.
  1048.  
  1049.  
  1050. FLOPPYDRIVES
  1051.  
  1052. This function returns the number of installed diskette drives in the
  1053. current computer system.
  1054.  
  1055. DECLARE FUNCTION FloppyDrives% ()
  1056.  
  1057. No calling parameters are required.
  1058.  
  1059.  
  1060. FREESPACE
  1061.  
  1062. You must supply the drive number of the diskette or fixed-disk which you
  1063. want to test (1 = drive A:, 2 = drive B:, etc). Pass a value of zero to
  1064. test the currently-logged or default drive. The amount of free space is
  1065. returned in bytes.
  1066.  
  1067. DECLARE FUNCTION FreeSpace& (BYVAL DriveNo%)
  1068.  
  1069. Note:       The return value will not be reliable if the drive being
  1070.             tested has an extended DOS partition which contains more
  1071.             than 32MB of free space.
  1072.  
  1073.  
  1074. GAMESPORT
  1075.  
  1076. This function checks to see if the host computer is fitted with an adaptor
  1077. for joysticks or a games paddle.
  1078.  
  1079. No calling parameters are required.
  1080.  
  1081. DECLARE FUNCTION GamesPort% ()
  1082.  
  1083. Returns logical TRUE (-1) if a games adaptor is present or FALSE (0) if no
  1084. games adaptor is fitted.
  1085.  
  1086.  
  1087. GRAPRINT
  1088.  
  1089. This routine simply serves as a function despatcher for the various
  1090. graphics text procedures, which can also be called directly. It is
  1091. intended to be called from programs which must run under a variety of
  1092. video adaptors, transferring control to the proper routine for the current
  1093. video mode. The calling program must supply appropriate parameters,
  1094. however.
  1095.  
  1096. DECLARE SUB GraPrint (BYVAL xLoc%, BYVAL yLoc%, Text$,_
  1097.                       BYVAL Attr%, BYVAL Scale%)
  1098.  
  1099. GRAPRINT provides a convenient way of displaying text in any of the EGA,
  1100. VGA and MCGA graphics modes (SCREENs 7-13) as well as the 320 x 200 pixel
  1101. 4-colour CGA mode (SCREEN 1) without having to bother about loading
  1102. external font files. It uses the standard character definition tables
  1103. built into your display adaptor, but allows you to scale them up to eight
  1104. times normal size and to specify any combination of foreground and
  1105. background colours supported by the current video mode.
  1106.  
  1107. XLOC%       The horizontal co-ordinate of the top left hand pixel
  1108.             from which the text will begin
  1109.  
  1110. YLOC%       The vertical co-ordinate of the top left hand pixel
  1111.             from which the text will begin
  1112.  
  1113. TEXT$       The string of text to be displayed (up to 63 characters).
  1114.  
  1115. ATTR%       The colour (or display attribute in monochrome modes) to
  1116.             be given to the text. This is calculated by the formula:
  1117.  
  1118.             Colour% = (Background% * 256) + Foreground%
  1119.  
  1120.             The GRATTRIB function (see below) will perform this
  1121.             calculation for you, automatically, using the foreground
  1122.             and background values you supply.
  1123.  
  1124.             Foreground and Background values are in the ranges used
  1125.             by the current video mode (eg. 0 - 15 for SCREEN 9). The
  1126.             actual colours displayed depend upon your current PALETTE
  1127.             settings.
  1128.  
  1129.             Note:   supplying a value of -1 for background prevents
  1130.                     background pixels from being changed at all. This
  1131.                     allows text to be blended more naturally into a
  1132.                     complex graphics display, it is not supported in
  1133.                     320 x 200 4-colour mode, however.
  1134.  
  1135. SCALE%      The character size of the text to be displayed. This ranges
  1136.             from 1 to 8, where 1 is standard 80-column text (40-column
  1137.             in SCREEN 7) and 8 multiplies the character size by eight
  1138.             on both the horizontal and vertical axes.
  1139.  
  1140. GRAPRINT can handle both byte-aligned and non byte-aligned characters. The
  1141. x, y co-ordinates you supply do not need to correspond to a row, column
  1142. character cell in SCREEN 0, the alphanumeric mode. The complete extended
  1143. ASCII character set is supported, including foreign symbols and box-
  1144. drawing characters (computers with CGA adaptors must have GRAFTBL loaded
  1145. to access characters above ASCII 127, however).
  1146.  
  1147. Since GRAPRINT does not support clipping, to ensure a clean display you
  1148. must ensure that the text to be output fits within the current screen
  1149. boundaries.
  1150.  
  1151. See also CGATEXT for displaying characters in SCREEN 1, MCGATEXT for
  1152. displaying characters in SCREEN 13 and VGATEXT for displaying text in
  1153. the EGA and VGA video modes (SCREENs 7-12).
  1154.  
  1155.  
  1156. HELPMATE
  1157.  
  1158. This routine provides a context-sensitive on-line Help facility for your
  1159. QuickBASIC programs.
  1160.  
  1161. DECLARE SUB HelpMate (BYVAL Colour%, Title$, BYVAL Context%, Topic$)
  1162.  
  1163. Colour%   is the display attribute to be given to the Help window. If a
  1164.           value of zero is passed, HELPMATE uses default colours which
  1165.           are Black on Cyan for colour screens and inverse video for a
  1166.           monochrome display.
  1167.  
  1168. Title$    is an optional Title for the Help window. If one is supplied
  1169.           it must be no longer than 48 characters so that it can be
  1170.           easily centered in the top row of the window. If Title$ is a
  1171.           null string, HELPMATE uses its' own name as a default.  
  1172.  
  1173. Context%  is the context-sensitive flag. If set to 1, then the routine
  1174.           attempts to load the file specified by ...
  1175.  
  1176. Topic$    A legal DOS filename (up to 8 characters without extension),
  1177.           specifying the name of the Topic file to be displayed. 
  1178.           HelpMate automatically appends the extension '.HLP'.  
  1179.  
  1180. If Context% is not set, (or Topic$ is a null string), then the routine
  1181. displays a list of topics, from which you can make your own selection.
  1182.  
  1183. If Context% is set, HELPMATE will display the first page of the Topic file
  1184. specified, otherwise it begins by  overlaying the current screen with a
  1185. popup window in which is listed those HELP topics available.
  1186.  
  1187. The first topic in the list is highlighted and you can move the highlight
  1188. around the menu with the arrow keys Highlight the topic you want, then
  1189. press the <RETURN> key. The first page of that topic will be displayed in
  1190. the HELP window.
  1191.  
  1192. Page backwards and forwards through the file using the <PG UP> and <PG DN>
  1193. keys. If you page past the end of the file you will be returned to the
  1194. topic list, where you can either select another topic, or press <ESC> to
  1195. return to the QuickBASIC program. On return, the original screen and all
  1196. current variables are restored, intact, and program execution will
  1197. continue with the statement following the procedure call.
  1198.  
  1199. By default, the Toolbox Help system looks for its topic files in a sub-
  1200. directory called HELP, beneath the currently-logged directory. You can,
  1201. however, direct it to look elsewhere for files by setting a HELP variable
  1202. in the DOS environment table
  1203.  
  1204. e.g.  SET HELP=C:\BASIC\TOOLBOX\HELP
  1205.  
  1206. Alternatively, you can use the QuickBASIC ENVIRON statement within your
  1207. program, to point HELPMATE to the appropriate pathname. Remember, though,
  1208. that this method only remains in effect as long as the current program is
  1209. running and that there must be enough environment space available to hold
  1210. the HELP directory pathname.
  1211.  
  1212. A set of example Topic files, for use with the demonstration program,
  1213. DEMON.EXE is supplied with the Assembly-Language ToolBox. You can make
  1214. your own, using any Word Processor or Text Editor which can output plain
  1215. ASCII text (EDLIN will do). If you do so, bear in mind that the HelpMate
  1216. window's maximum page size is 16 rows of 55-column text. The maximum
  1217. number of pages in any one file is 256.
  1218.  
  1219.                              TIP
  1220.  
  1221. When displaying the list of available Topics, HelpMate searches the
  1222. current HELP directory for files with the extension .HLP. However, since
  1223. there is only room for 60 such filenames to be displayed in the menu
  1224. window, any files in excess of this number will be not be listed and are,
  1225. hence, inaccessible. You can, however, read any number of Context-
  1226. sensitive topic files since these are named explicitly in the call to
  1227. HelpMate which loads them. They need not, therefore, appear in the Topic
  1228. list.
  1229.  
  1230. If your application needs to provide a large number of Topic files, it is
  1231. a good idea to hide those which are context-sensitive from normal
  1232. directory searches (you can use the Toolbox Hide function to do this).
  1233. This will not prevent these files from being loaded when called, but it
  1234. does prevent them from appearing in the Topic list which gives you more
  1235. room for those general-purpose topic files which are selected by the user.
  1236.  
  1237. Note:       The \HELP directory on the ToolBox distribution disk
  1238.             contains a number of these hidden files for use by the
  1239.             demonstration program DEMON.EXE.
  1240.  
  1241.  
  1242. HIDE
  1243.  
  1244. Toggles the Hidden bit of the specified file's directory entry, making it
  1245. visible or invisible to directory listings.
  1246.  
  1247. DECLARE SUB Hide (BYVAL Switch%, FileSpec$)
  1248.  
  1249. If SWITCH% = 1 the file is hidden (regardless of whether it is currently
  1250. visible or not), any other value makes the file visible. FileSpec$ is the
  1251. name of the file to be hidden or unhidden. It can include a drive letter
  1252. and directory path but must be an explicit pathname, wildcard characters
  1253. are not allowed.
  1254.  
  1255.  
  1256. INTERVAL
  1257.  
  1258. Calculate the number of days between two dates supplied as long integer
  1259. Julian numbers. You can use the DAYNUMBER function (see above) to turn
  1260. dates in normal numeric format into Julian numbers and NUMBERDAY (below)
  1261. to convert them back again.
  1262.  
  1263. DECLARE FUNCTION Interval& (First&, Second&)
  1264.  
  1265. This function always returns a positive value, regardless of whether the
  1266. first argument is lower or greater than the second.
  1267.  
  1268.  
  1269. ITPRINT
  1270.  
  1271. Sends the text supplied, to the printer, as a string of italic characters.
  1272. Output begins at the current print position and can, optionally, append a
  1273. carriage-return/linefeed to take the print head to the beginning of a new
  1274. line when finished.
  1275.  
  1276. DECLARE SUB ItPrint (BYVAL Printer%, Buffer$, BYVAL NewLine%)
  1277.  
  1278. Arguments:  Printer%    the parallel port output is to be sent to
  1279.                         (1 = LPT1:, 2 = LPT2:, etc.).
  1280.             Buffer$     the string of text to be printed.
  1281.             NewLine%    set this to a non-zero value if you want 
  1282.                         to move to a new line after printing.
  1283.  
  1284. The routine restores the previous print style or font before it returns
  1285. and does not effect subsequent output to the printer, using the QuickBASIC
  1286. LPRINT or PRINT # statements.
  1287.  
  1288. Note:       The version of this routine stored in the Toolbox
  1289.             library is for EPSON compatible printers. If you have
  1290.             an IBM graphics printer or ProPrinter, then you should
  1291.             rebuild your libraries, using either the PRINTIBM.OBJ
  1292.             or PRINTPRO.OBJ object module in place of PRINTEPS.OBJ.
  1293.  
  1294.  
  1295. KEYFLAGS
  1296.  
  1297. Returns a 16-bit unsigned number which is bit-encoded with the current
  1298. status of the CTRL, ALT, INSERT and other keyboard control keys.
  1299.  
  1300. No calling parameters are required.
  1301.  
  1302. DECLARE FUNCTION KeyFlags% ()
  1303.  
  1304. The BITTEST function (see below) can be used to isolate individual bits of
  1305. the returned value. Their meanings are as follows:
  1306.  
  1307.  F E D C B A 9 8 7 6 5 4 3 2 1 0   Bits
  1308. ┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
  1309. │0│0│0│0│0│0│0│0│0│0│0│0│0│0│0│0│  Meaning if set
  1310. └─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
  1311.  │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─┴─  Left & Right SHIFT keys pressed
  1312.  │ │ │ │ │ │ │ │ │ │ │ │ │ └─────  CTRL key pressed
  1313.  │ │ │ │ │ │ │ │ │ │ │ │ └───────  ALT key pressed
  1314.  │ │ │ │ │ │ │ │ │ │ │ └─────────  SCROLL LOCK active
  1315.  │ │ │ │ │ │ │ │ │ │ └───────────  NUM LOCK active
  1316.  │ │ │ │ │ │ │ │ │ └─────────────  CAPS LOCK active
  1317.  │ │ │ │ │ │ │ │ └───────────────  INSERT key status
  1318.  │ │ │ │ │ │ │ └─────────────────  Left CTRL key pressed
  1319.  │ │ │ │ │ │ └───────────────────  Left ALT key pressed
  1320.  │ │ │ │ │ └─────────────────────  SYS REQ key pressed
  1321.  │ │ │ │ └───────────────────────  PAUSE (or CTRL-NUM LOCK) active 
  1322.  │ │ │ └─────────────────────────  SCROLL LOCK pressed
  1323.  │ │ └───────────────────────────  NUM LOCK pressed
  1324.  │ └─────────────────────────────  CAPS LOCK pressed
  1325.  └───────────────────────────────  INSERT key pressed
  1326.  
  1327. See the CAPSLOCK, NUMLOCK and SCRLOCK functions for a method of setting or
  1328. reading the status of specific control keys.
  1329.  
  1330.  
  1331. KEYFLUSH
  1332.  
  1333. This procedure flushes the keyboard type-ahead buffer and discards any
  1334. keystrokes which have not yet been processed.
  1335.  
  1336. No calling parameters are required.
  1337.  
  1338. DECLARE SUB KeyFlush ()
  1339.  
  1340. Note:       KEYFLUSH may not work properly if you have installed
  1341.             keystroke enhancement software which moves the type-ahead
  1342.             buffer to another location in memory. It DOES work with
  1343.             command-line buffers like IBM's DOSEDIT, however.
  1344.  
  1345.  
  1346. KEYIN
  1347.  
  1348. Similar to the QuickBASIC INKEY$ function, except that it waits for a
  1349. keypress instead of returning at once if none is available.
  1350.  
  1351. No calling parameters are required.
  1352.  
  1353. DECLARE FUNCTION KeyIn% ()
  1354.  
  1355. The function returns a numeric value between 0 and 255 which represents
  1356. the ASCII code of the key pressed. If one of the function keys (F1 to F12)
  1357. or a special key such as PAGEUP or one of the cursor arrows is pressed,
  1358. then a negative value is returned. Converting this number to its absolute
  1359. equivalent produces the scan code of the key.
  1360.  
  1361. Example:  KeyPress% = KeyIn%
  1362.           IF KeyPress% < 0 THEN
  1363.              ScanCode% = ABS(KeyPress%)
  1364.           ELSE
  1365.              AsciCode% = KeyPress%
  1366.           END IF
  1367.  
  1368. See the ASCICODE topic for a list of ASCII codes and their equivalent
  1369. printable characters. The SCANCODE topic lists the scan codes returned by
  1370. the various function and control keys.
  1371.  
  1372. The KEYIN function will recognise if one of the new 101/102 extended
  1373. keyboards is being used and return the correct scan codes for the extra
  1374. keys such as F11 and F12.
  1375.  
  1376.  
  1377. KEYSTAT
  1378.  
  1379. This function tests to see if a keystroke is waiting to be read. It does
  1380. not read or remove the keystroke from the typeahead buffer, use KEYIN% or
  1381. INKEY$ to do this.
  1382.  
  1383. No calling parameters are required.
  1384.  
  1385. DECLARE FUNCTION KeyStat% ()
  1386.  
  1387. KEYSTAT returns -1 (logical TRUE) if a keystroke is waiting to be
  1388. collected or 0 (logical FALSE) if the typeahead buffer is empty.
  1389.  
  1390.  
  1391. LPTSWAP
  1392.  
  1393. This procedure swaps the port addresses of the two printer channels
  1394. specified so that, for example, all output targeted to LPT1: will actually
  1395. be sent to LPT4:, and vice-versa.
  1396.  
  1397. DECLARE SUB LptSwap (BYVAL Printer1%, BYVAL Printer2%)
  1398.  
  1399. Printer1% and Printer2% are both numeric values in the range 1 - 4, where
  1400. 1 = LPT1:, 2 = LPT2:, etc.
  1401.  
  1402. Note:       any changes made using LPTSWAP will remain in effect 
  1403.             even after your program is finished.
  1404.  
  1405.  
  1406. MATHSCHIP
  1407.  
  1408. Checks to see if a floating-point maths co-processor is installed in the
  1409. system. 
  1410.  
  1411. No calling parameters are required.
  1412.  
  1413. DECLARE FUNCTION MathsChip% ()
  1414.  
  1415. MATHSCHIP returns 0 (logical FALSE) if no co-processor is available. A
  1416. non-zero value indicates that a co-processor is available and, in this
  1417. case, the function will attempt to identify it. Possible return values
  1418. are:
  1419.  
  1420.      87 =   Intel 8087
  1421.     287 =   Intel 80287
  1422.     387 =   Intel 80387 (or 80486 with built-in maths processor)
  1423.  
  1424. Waitek and other models return the same values as their Intel equivalents.
  1425.  
  1426.  
  1427. MCGACOPY
  1428.  
  1429. Copies an MCGA screen to or from a user-supplied dynamic array.
  1430.  
  1431. DECLARE SUB McgaCopy (BYVAL Switch%, SEG Array)
  1432.  
  1433. SWITCH%     Direction of copy   0 = copy screen to string
  1434.                                 1 = copy string to screen
  1435.  
  1436. ARRAY       Dynamic INTEGER or LONG integer array to hold the screen
  1437.             image. It must contain at least 64000 bytes of storage
  1438.             (32000 elements for INTEGER or 16000 for LONG) or the
  1439.             routine will fail, with possibly disastrous results.
  1440.  
  1441. Note:       It is not enough just to pass the name of the storage
  1442.             array to MCGACOPY. You must explicitly name the element
  1443.             where screen storage is to start, eg:
  1444.  
  1445.             DIM ScreenArray(1 TO 32000) AS INTEGER
  1446.             SCREEN 13
  1447.                 .
  1448.             draw some stuff
  1449.                 .
  1450.             McgaCopy 0, ScreenArray(1)
  1451.  
  1452.  
  1453. The QuickBASIC PCOPY statement is very useful for storing screen pages in
  1454. memory, so that they can be kept out of sight until needed. Unfortunately
  1455. it only works in text modes or, on computers with EGA or VGA video cards,
  1456. in SCREEN modes 7 to 12. This routine, on the other hand, works only in
  1457. the MCGA display mode (SCREEN 13), it provides a useful alternative to the
  1458. PCOPY statement for use with medium-resolution 256-colour screens.
  1459.  
  1460. See CGACOPY for a version that can be used with SCREEN 1 and 2 displays.
  1461.  
  1462.  
  1463. MCGASCROLL
  1464.  
  1465. Scrolls a rectangular portion of a SCREEN 13 (320 x 200 256-colour)
  1466. display one pixel to the left or right, wrapping those pixels which are
  1467. scrolled out at the end round to the beginning again.
  1468.  
  1469. DECLARE SUB McgaScroll (BYVAL xLoc%, BYVAL yLoc%, BYVAL xPixels%,_
  1470.                         BYVAL yPixels%, BYVAL Direction%)                 
  1471.  
  1472. XLOC%       The horizontal (X) co-ordinate of the top-left corner of
  1473.             the rectangle to be scrolled.
  1474.  
  1475. YLOC%       The vertical (Y) co-ordinate of the top-left corner of
  1476.             the rectangle to be scrolled.
  1477.  
  1478. XPIXELS%    The width (in pixels) of the rectangle to be scrolled.
  1479.  
  1480. YPIXELS%    The height (in pixels) of the rectangle to be scrolled.
  1481.  
  1482. DIRECTION%  The direction in which the rectangle contents are to be
  1483.             scrolled (0 = Left, 1 = Right).
  1484.  
  1485. Co-ordinates are in the ranges:  X >= 0 <= 319, Y >= 0 <= 199
  1486.  
  1487.  
  1488. MCGATEXT
  1489.  
  1490. Writes characters to the screen in the 320 x 200  256-colour graphics
  1491. mode (SCREEN 13).
  1492.  
  1493. DECLARE SUB McgaText (BYVAL xLoc%, BYVAL yLoc%, Text$,_
  1494.                       BYVAL Attr%, BYVAL Scale%)
  1495.  
  1496. This routine provides a convenient way of displaying text in SCREEN 13
  1497. without having to bother about loading external font files. It uses the
  1498. standard character definition tables built into your display adaptor, but
  1499. allows you to scale them up to eight times normal size and to specify any
  1500. combination of foreground and background colours.
  1501.  
  1502. XLOC%       The horizontal co-ordinate of the top left hand pixel
  1503.             from which the text will begin (0 - 319).
  1504.  
  1505. YLOC%       The vertical co-ordinate of the top left hand pixel
  1506.             from which the text will begin (0 - 199).
  1507.  
  1508. TEXT$       The string of text to be displayed (up to 63 characters).
  1509.  
  1510. ATTR%       The colour (or display attribute in monochrome modes) to
  1511.             be given to the text. This is calculated by the formula:
  1512.  
  1513.             Colour% = (Background% * 256) + Foreground%
  1514.  
  1515.             Foreground is in the range (0 - 255) and Background (0 - 64).
  1516.             The actual colours displayed depend upon your current PALETTE
  1517.             settings.
  1518.  
  1519.             Note:   supplying a value of -1 for background prevents
  1520.                     background pixels from being changed at all. This
  1521.                     allows text to be blended more naturally into a
  1522.                     complex graphics display.
  1523.  
  1524. SCALE%      The character size of the text to be displayed. This ranges
  1525.             from 1 to 8, where 1 is standard 40-column text and where 8
  1526.             multiplies the character size by eight on both the horizontal
  1527.             and vertical axes.
  1528.  
  1529. The complete extended ASCII character set is supported, including foreign
  1530. symbols and box-drawing characters.
  1531.  
  1532. Since MCGATEXT does not support clipping, to ensure a clean display you
  1533. must ensure that the text to be output fits within the current screen
  1534. boundaries.
  1535.  
  1536. See also CGATEXT for displaying characters in SCREEN 1 and VCGATEXT for
  1537. displaying characters in SCREENs 7-12.
  1538.  
  1539.  
  1540. MISTAKE
  1541.  
  1542. Displays the error message supplied in a dialogue box and waits for the
  1543. operator to press the <ENTER> key before returning, restoring the screen
  1544. to its' previous state.
  1545.  
  1546. DECLARE SUB MisTake (BYVAL Row%, Message$, BYVAL Attr%, BYVAL Mouse%)
  1547.  
  1548. ROW%        The top row of the dialogue box when it is displayed. The
  1549.             box is automatically centered within this row, which may be
  1550.             adjusted so that it remains within the screen boundaries.
  1551.  
  1552. MESSAGE$    A string of text comprising the error message to be displayed.
  1553.             It must be no longer than 40 characters otherwise it will be
  1554.             truncated to fit inside the display panel.
  1555.  
  1556. ATTR%       The display attribute or colour to be given to the dialogue box.
  1557.             If an argument of zero is supplied, the box is displayed with
  1558.             bright yellow text on a red background (colour monitors) or in
  1559.             reverse video (monochrome monitors).
  1560.  
  1561. MOUSE%     Should be set to TRUE (-1) or FALSE (0) to indicate if a
  1562.             mouse is available for use. If available, the operator can
  1563.             respond by clicking the left mouse button while the cursor is
  1564.             positioned on the radio button.     
  1565.  
  1566. Note:       No meaningful value is returned by the procedure.
  1567.  
  1568.  
  1569. NETTEST
  1570.  
  1571. This function is used to detect if the program which calls it is running
  1572. under a Novell Network. It can be used to decide if file or record locking
  1573. is required.
  1574.  
  1575. No calling parameters are required.
  1576.  
  1577. DECLARE FUNCTION NetTest% ()
  1578.  
  1579. Returns -1 (logical TRUE) if the Network shell is present and 0 (logical
  1580. FALSE) if not. Note that the function cannot distinguish between programs
  1581. running on a local or network drive under NetWare.
  1582.  
  1583.  
  1584. NUMBERDAY
  1585.  
  1586. Splits a Julian date number into day, month and year and also returns the
  1587. day of the week as a number between 0 and 6 (0 = Sunday etc..)
  1588.  
  1589. DECLARE FUNCTION NumberDay% (Number&, Day%, Month%, Year%)
  1590.  
  1591.  
  1592. NUMLOCK
  1593.  
  1594. Toggles NUM LOCK on or off or, alternatively, reads the current NUM LOCK
  1595. key setting.
  1596.  
  1597. DECLARE FUNCTION NumLock% (BYVAL Switch%)
  1598.  
  1599. Switch% = 0  Turns NUM LOCK off
  1600.         = 1  Turns NUM LOCK on
  1601.  
  1602. Any other value just returns the current NUM status as a logical value
  1603. where -1 (TRUE) means that NUM LOCK is on and 0 (FALSE) means that NUM
  1604. LOCK is off.
  1605.  
  1606.  
  1607. PARALLELPORTS
  1608.  
  1609. This function checks how many hardware printer ports are available. It
  1610. does not check to see if an actual printer is connected to each of them,
  1611. use the PRINTEST or PRINTERSTAT functions (see below) to obtain this
  1612. information.
  1613.  
  1614. No calling parameters are required.
  1615.  
  1616. DECLARE FUNCTION ParallelPorts% ()
  1617.  
  1618.  
  1619. PAUSE
  1620.  
  1621. This routine is used to generate machine-independent timing loops. It
  1622. simply pauses until the specified number of clock ticks have elapsed.
  1623.  
  1624. DECLARE SUB Pause (BYVAL Ticks%)
  1625.  
  1626. There are 18.2 clock ticks per second on all PCs, no matter what the
  1627. processor or processor speed.
  1628.  
  1629.  
  1630. PEEKWORD
  1631.  
  1632. Reads a long integer value from two consecutive bytes of memory.
  1633.  
  1634. DECLARE FUNCTION PeekWord& (BYVAL Segment&, BYVAL Offset&)
  1635.  
  1636. Arguments:  Segment&  = address of memory segment containing the data
  1637.                         to be read.
  1638.             Offset&   = offset address, within the segment of the 
  1639.                         two bytes to be read.
  1640.  
  1641. Returns:    contents of the two consecutive bytes in the form of a
  1642.             long integer value in the range (0 to 65535). 
  1643.  
  1644. Note:       parameters are passed as LONG integers to save you the
  1645.             hassle of having to convert argument values over 32767
  1646.             to negative signed integers. Do not use values greater
  1647.             than 65535, however, or the most significant word will
  1648.             be ignored and the address converted to Modulus 65536.
  1649.  
  1650.             If you supply an offset address of 65535 (0FFFFh) which
  1651.             would cause the second byte to cross a segment boundary,
  1652.             only the lower byte is read and returned as a value
  1653.             between (0 - 255).
  1654.  
  1655. Using QuickBASIC's PEEK function to examine data which lies outside
  1656. of DGROUP is a pain. You also have to use DEF SEG to set the segment
  1657. required and then to reset it afterwards. This function allows you to
  1658. read data, directly, from anywhere in the 1 megabyte of addressable
  1659. RAM space your computer contains. It also reads two adjacent bytes of
  1660. data from the address supplied and converts them to a single integer.
  1661.  
  1662. The PC architecture follows the Intel convention of storing 'words'
  1663. (two-byte values) with the Least Significant part in the lower byte
  1664. (LSB) and the Most Significant (MSB) in the higher byte. Since each
  1665. byte can only hold 256 possible values (0 to 255), an integer which
  1666. has a range of from 0 to 65535 (unsigned) is stored in consecutive
  1667. bytes with the MSB being considered the number of times it can be
  1668. divided by 256 and the LSB being the remainder of this division. The
  1669. number 1000, for example would be stored in memory as follows:
  1670.  
  1671.                          LSB              MSB
  1672.                  ┌─┬─┬─┬─┬─┬─┬─┬─┐ ┌─┬─┬─┬─┬─┬─┬─┬─┐
  1673. 1000 (decimal) = │1│1│1│0│1│0│0│0│ │0│0│0│0│0│0│1│1│
  1674.                  └─┴─┴─┴─┴─┴─┴─┴─┘ └─┴─┴─┴─┴─┴─┴─┴─┘
  1675.  
  1676.                  1000 MOD 256 = 232   1000 \ 256 = 3
  1677.  
  1678. To convert the two bytes back to a single integer again, you would
  1679. use the formula: 
  1680.  
  1681.                         x = (MSB * 256) + LSB 
  1682.  
  1683. or, in our example:     x = 3 * 256 + 232 = 1000
  1684.  
  1685. PEEKWORD makes this conversion for you automatically, all you have to
  1686. do is supply the address and it returns the contents of the two bytes
  1687. in long integer format.
  1688.  
  1689. The POKEWORD procedure (below) complements PEEKWORD by allowing you
  1690. to write a word of data anywhere in the 1MB addressable PC workspace.
  1691.  
  1692. See also FARPEEK and FARPOKE which allow you to read from and write
  1693. to far memory, one byte at a time.
  1694.  
  1695.  
  1696. POKEWORD
  1697.  
  1698. Writes an integer value into two consecutive bytes of memory.
  1699.  
  1700. DECLARE SUB PokeWord (BYVAL Segment&, BYVAL Offset&, BYVAL Word&)
  1701.  
  1702. Arguments:  Segment&  = address of memory segment containing the
  1703.                         location to be written to
  1704.             Offset&   = offset address, within the segment of the 
  1705.                         two bytes to be set.
  1706.             Word&     = the value to set in memory. It must be a
  1707.                         value in the range 0 to 65535.
  1708.  
  1709. The data is written in standard Intel format, with the Most
  1710. Significant part of the number (MSB) being written into the higher
  1711. of the two bytes.
  1712.  
  1713. Note:       if you supply an offset address of 65535 (0FFFFh) which
  1714.             would cause the second byte to cross a segment boundary,
  1715.             only the lower, least significant, byte (LSB) is written.
  1716.  
  1717.             Parameters are passed as LONG integers to save you the
  1718.             hassle of having to convert argument values over 32767
  1719.             to negative signed integers. Do not use values greater
  1720.             than 65535, however, or the most significant word will
  1721.             be ignored and the address converted to Modulus 65536.
  1722.  
  1723. The PEEKWORD procedure (above) complements POKEWORD by allowing you
  1724. to read a word of data from anywhere in the 1MB of addressable PC
  1725. memory.
  1726.  
  1727. See also FARPEEK and FARPOKE which allow you to read from and write
  1728. to far memory, one byte at a time.
  1729.  
  1730.  
  1731. POPUP
  1732.  
  1733. This is the Toolbox popup window generator. What are Windows?  Well if
  1734. you've used the QuickBASIC environment at all then you've used Windows.
  1735. When you press <ALT><F> to bring down the File Menu, the list of options
  1736. presented there is in a window. Notice how any characters which were
  1737. concealed when the File Menu appeared, are restored, intact, after you've
  1738. made your choice. Windows are areas of the screen which are used to hold
  1739. transient data and messages to the user. They make the most of the limited
  1740. display space available and remove the need to constantly rebuild the
  1741. screen, each time your program communicates with the world.
  1742.  
  1743. Properly  presented, windows can give the illusion of multi-tasking, even
  1744. on single-processor machines like the IBM-PC.
  1745.  
  1746. Nowadays, no program worth its' salt can be without a window of some kind.
  1747. If YOUR program is going to stand out amongst all the others, however,
  1748. they've got to be done professionally. Windows must appear instantly and
  1749. vanish, just as quickly, when no longer required. They must be as large or
  1750. as small as is necessary, for the data which you need to display, and you
  1751. should have a plentiful supply, for all the circumstances that your
  1752. program might encounter. BASIC, unfortunately, is just not fast enough to
  1753. meet all these requirements.
  1754.  
  1755. Looks like it'll have to be Assembly-Language again ...
  1756.  
  1757. DECLARE SUB PopUp (BYVAL Row%, BYVAL Col%, BYVAL Hght%, BYVAL Wdth%,_
  1758.                    BYVAL Attr%, BYVAL Brdr%, BYVAL Shdw%, BYVAL Zoom%)
  1759.  
  1760. Opens a popup window at the screen location specified.
  1761.  
  1762. Where:    P1%  is the top-left row co-ordinate
  1763.           P2%  is the top-left column co-ordinate
  1764.           P3%  is the height (in rows) of the window
  1765.           P4%  is the width (in columns) of the window
  1766.           P5%  is the display attribute or colour
  1767.           P6%  is the border style (0 = no border)
  1768.           P7%  is the shadow switch (0 = no shadow)
  1769.           P8%  is the zoom switch (0 = no zoom)
  1770.  
  1771. The first four parameters specify the size of the window and the location
  1772. on the screen at which it will appear. Border styles are as follows:
  1773.  
  1774. ┌────┐
  1775. │ 1. │    Single-lined box all round the window
  1776. └────┘
  1777. ╔════╗
  1778. ║ 2. ║    Double-lined box all round the window
  1779. ╚════╝
  1780. ╒════╕
  1781. │ 3. │    Single vertical, double horizontal
  1782. ╘════╛
  1783. ╓────╖
  1784. ║ 4. ║    Single horizontal, double vertical
  1785. ╙────╜
  1786. ╤════╤
  1787. │ 5. │    Single-lined box all round the window
  1788. ╘════╛
  1789. ╦════╦
  1790. ║ 6. ║    Double-lined box all round the window
  1791. ╚════╝
  1792. ┬────┬
  1793. │ 7. │    Single vertical, double horizontal
  1794. ╘════╛
  1795. ╥────╥
  1796. ║ 8. ║    Single horizontal, double vertical
  1797. ╙────╜
  1798.  
  1799. Border styles 5 through 8 are particularly suitable for use with pull-
  1800. down menus, descending from a horizontal bar.
  1801.  
  1802. The SHADOW switch (Parameter 7), can be used to add a black shadow beneath
  1803. your window, Giving it a three dimensional effect. Setting P7% to 1 puts
  1804. solid shadow on the left-hand side. Setting P7% to 2 puts it on the right.
  1805. values of 3 and 4 in P7% will display transparant shadow to the left or
  1806. right, respectively, any other value prevents shadow.
  1807.  
  1808. Setting Parameter 8 to a non-zero value will cause the window to ZOOM onto
  1809. the screen.  What this means is that, starting at a point source,
  1810. successively larger versions of the window will be drawn until it is the
  1811. size required. The value you supply sets the interval, in milliseconds,
  1812. between iterations and is used to control the speed at which the window
  1813. explodes onto the screen. 
  1814.  
  1815. To preserve compatibility with programs written for use with previous
  1816. versions of the Toolbox, a value of 1 in parameter 8 sets the default
  1817. delay of 20 milliseconds per iteration. At this speed, which is constant
  1818. on PCs with all types of microprocessor, the process is extremely fast
  1819. and impressive, and adds a very professional touch to your programs. 
  1820.  
  1821. Before a window is opened, the display area below it is copied to an
  1822. internal buffer, from where it will be eventually restored when the window
  1823. is closed. This buffer has a capacity of 8 KiloBytes, the equivalent of
  1824. two full screens. To calculate the storage required for a particular
  1825. window, use the formula:
  1826.  
  1827. Bytes = ((Height in rows * Width in columns) * 2) + 6
  1828.  
  1829. (add one row to the height and one column to the width if you specify
  1830. shadow)
  1831.  
  1832. The window area needs to be multiplied by 2 since each screen character
  1833. takes two bytes of memory, for itself and its attribute code. The odd six
  1834. bytes are required for the storage of buffer pointers. The window buffer
  1835. works as a LIFO (Last In First Out) stack, so that the last window opened
  1836. is the first one to be removed. You can close the current window with the
  1837. statement:
  1838.  
  1839. CALL ShutUp
  1840.  
  1841. To put text inside a window, use the FASTPRINT routine (see above). You
  1842. can clear all or part of an open window with SCROLL (see below).
  1843.  
  1844.  
  1845. PRINTERSTAT
  1846.  
  1847. DECLARE FUNCTION PrinterStat% (BYVAL Printer%)
  1848.  
  1849. This function tests the current status of the parallel printer specified.
  1850. The value returned is tested as follows :
  1851.  
  1852.    Bit     Wanted    Meaning
  1853. ─────────────────────────────────────────────────────
  1854.     7        1       Printer not busy (0 = busy)
  1855.     6        0       Printer acknowledges
  1856.     5        0       Out-of-paper
  1857.     4        1       This printer selected
  1858.     3        0       I/O error
  1859.     2        0       Not used
  1860.     1        0       Not used
  1861.     0        0       Time-out occurred
  1862. ─────────────────────────────────────────────────────
  1863.    90 Hex  144 (Decimal)
  1864.  
  1865. Specify the printer to be tested as a number between 1 and 4, where 1 =
  1866. LPT1:, 2 = LPT2:, etc.
  1867.  
  1868. Note:       Some printers also set the acknowledgement bit. If so, the
  1869.             value returned will be 208 (D0 Hex) instead of 144.
  1870.  
  1871.  
  1872. PRINTEST
  1873.  
  1874. This is a simplified version of the PRINTERSTAT function (above). It
  1875. returns a logical value to indicate whether the specified printer is ready
  1876. (TRUE = -1) or not (FALSE = 0).
  1877.  
  1878. DECLARE FUNCTION PrinTest% (BYVAL Printer%)
  1879.  
  1880. Specify the printer to be tested as a number between 1 and 4, where 1 =
  1881. LPT1:, 2 = LPT2:, etc. The function will only work with parallel printers.
  1882.  
  1883.  
  1884. PRINTSET
  1885.  
  1886. Most modern printers have a variety of useful styles and fonts which you
  1887. can select by setting dip switches or sending the appropriate control
  1888. codes from the computer. Unfortunately this is not always convenient,
  1889. especially when you are in the middle of a program and have to duck out to
  1890. set up the proper print size. PRINTSET offers a solution to this problem
  1891. in the form of a pull-down menu which allows you to select from a range of
  1892. printer features, using the 'point-and-shoot' method.
  1893.                                                     
  1894. DECLARE SUB PrintSet (BYVAL Row%, BYVAL Col%, BYVAL Attr%, BYVAL Printer%)
  1895.  
  1896. Where:  Row%     = Row number of the top left-hand corner of the menu
  1897.                    window.
  1898.         Col%     = Column number of the top left-hand corner of the menu
  1899.                    window. 
  1900.         Attr%    = the display attribute or colour which is given to the
  1901.                    menu window.
  1902.         Printer% = the printer number (i.e. 1 = LPT1, 2 = LPT2 etc).
  1903.  
  1904. If you supply a value of zero for the Attr% argument, the menu window will
  1905. take the colour or attribute of the character which will be overlaid by
  1906. the top left corner of the window, when it appears. If this character is
  1907. also a single or double-lined horizontal bar (ASCII 196 or 205), the
  1908. border of the menu will be automatically adjusted to blend in with this
  1909. line, allowing you to produce the appearance of a pulldown menu.
  1910.  
  1911. Note:       Although the Toolbox package contains copies of this module
  1912.             configured for different types of printer, only one version
  1913.             of PrintSet may be in the library at any one time.
  1914.  
  1915.             PRINTEPS.OBJ is for Epson printers
  1916.             PRINTIBM.OBJ is for IBM Grahics printers
  1917.             PRINTPRO.OBJ is for IBM Proprinters
  1918.  
  1919.  
  1920. RAMDISK
  1921.  
  1922. Many disk-intensive processes, such as file sorting, will run much faster
  1923. when performed on a ramdisk. In such cases, use this function to test if a
  1924. ramdisk is available and the FREESPACE function (above) to see if it has
  1925. enough space for the job required. Don't forget to copy your data back to
  1926. a physical drive afterwards, or you will lose it when you power off.
  1927.  
  1928. RAMDISK searches the system drive table and examines the device driver for
  1929. each block device to see if it is a ramdisk. If one is detected, the
  1930. function returns the ASCII value of the drive letter associated with it
  1931. (eg 68 = D:). If no ramdisk is present, a value of zero is returned. If
  1932. more than one ramdisk is present in the system, only the first one is
  1933. reported on.
  1934.  
  1935. No calling parameters are required.
  1936.  
  1937. DECLARE FUNCTION RamDisk% ()
  1938.  
  1939. RAMDISK will work reliably with all versions of Microsoft's RAMDRIVE and
  1940. IBM's VDISK. However it has not been tested with any of the more esoteric
  1941. virtual disk products, and may not correctly identify some of these.
  1942.  
  1943.  
  1944. RAND
  1945.  
  1946. Returns a random number. This differs from QuickBASIC's RND function in
  1947. that RAND returns an integer and you can specify the range for this value.
  1948.  
  1949. DECLARE FUNCTION Rand% (BYVAL Lower%, BYVAL Higher%)
  1950.  
  1951. Lower% and Higher% are the upper and lower limits for the random number
  1952. to be returned. If Lower% is greater than Higher% then the arguments will
  1953. be transposed.
  1954.  
  1955.  
  1956. RESEED
  1957.  
  1958. Reinitialises the random number seed used by the RAND function (above).
  1959.  
  1960. DECLARE SUB ReSeed (BYVAL Seed&)
  1961.  
  1962. Note that the argument passed is a LONG integer. This enables you to use
  1963. the value which is returned by the QuickBASIC TIMER function, eg:
  1964.  
  1965.     ReSeed TIMER
  1966.  
  1967. Note that the Toolbox random number seed is not the same as the one used
  1968. internally by QuickBASIC. You cannot, therefore, start a new sequence of
  1969. QB's RND values by using RESEED nor can you use RANDOMIZE to reinitialise
  1970. the sequence for RAND.
  1971.  
  1972. SCREENDUMP
  1973.  
  1974. Copies the contents of the current screen (text mode only) to the line
  1975. printer, just as if the operator had pressed the <Prt Scrn> key.
  1976.  
  1977. No calling parameters are required.
  1978.  
  1979. DECLARE SUB ScreenDump ()
  1980.  
  1981. Includes support for 43 and 50-line screens on EGA and VGA adaptors.
  1982.  
  1983. This routine will not work if screen print has previously been disabled by
  1984. a call to the DISABLEPRTSC routine (see above) or if the parallel printer
  1985. at LPT1: is not ready.
  1986.  
  1987.  
  1988. SCREENROWS
  1989.  
  1990. Returns the height of the current screen, in rows, as set by the last
  1991. WIDTH statement (default = 25).
  1992.  
  1993. No calling parameters are required.
  1994.  
  1995. DECLARE FUNCTION ScreenRows% ()
  1996.  
  1997. The number returned may be 25, 43 or 50, depending on the capabilities of
  1998. your display adaptor.
  1999.  
  2000.  
  2001. SCREENWIDTH
  2002.  
  2003. Returns the width of the current screen, in columns, as set by the last
  2004. WIDTH statement.
  2005.  
  2006. No calling parameters are required.
  2007.  
  2008. DECLARE FUNCTION ScreenWidth% ()
  2009.  
  2010. Possible return values are 40 and 80 (default = 80).
  2011.  
  2012.  
  2013. SCRLOCK
  2014.  
  2015. Toggles SCROLL LOCK on or off or, alternatively, reads the current SCROLL
  2016. LOCK key setting.
  2017.  
  2018. DECLARE FUNCTION ScrLock% (BYVAL Switch%)
  2019.  
  2020. Switch% = 0  Turns SCROLL LOCK off
  2021.         = 1  Turns SCROLL LOCK on
  2022.  
  2023. Any other value just returns the current SCROLL status as a logical value
  2024. where -1 (TRUE) means that SCROLL LOCK is on and 0 (FALSE) means that the
  2025. SCROLL LOCK is off.
  2026.  
  2027.  
  2028. SCROLL
  2029.  
  2030. Scrolls the contents of a screen rectangle a specified number of lines or
  2031. columns in the direction indicated, blank spaces of the background colour
  2032. specified are scrolled in to replace them.
  2033.  
  2034. DECLARE SUB Scroll (BYVAL Dir%, BYVAL Y1%, BYVAL X1%, BYVAL Y2%,_
  2035.                     BYVAL X2%, BYVAL Units%, BYVAL Attr%)
  2036.  
  2037. Dir%        =  Scroll direction (0 = down, 1 = up, 2 = left, 3 = right).
  2038. Y1%         =  Top-left row of rectangle to be scrolled.
  2039. X1%         =  Top-left column of rectangle.
  2040. Y2%         =  Bottom-right row of rectangle.
  2041. X2%         =  Bottom-right column of rectangle
  2042. Units%      =  Number of rows or columns to scroll.
  2043. Attr%       =  Display attribute of blank spaces scrolled in.
  2044.  
  2045. Notes:      This routine will work in all graphics modes as well as on
  2046.             the text screen. When scrolling the graphics screen up or
  2047.             down, however, the attribute value must be calculated in a
  2048.             different way:
  2049.  
  2050.             On 320 x 200 4-colour and 640 x 200 2-colour displays the
  2051.             attribute represents a 1-byte pixel pattern, which is
  2052.             equivalent to 8 pixels in 2-colour (SCREEN 2) mode and 4
  2053.             pixels in 4-colour (SCREEN 1) mode. This pixel pattern is
  2054.             replicated through all the blank lines scrolled in.
  2055.  
  2056.             In all other EGA, VGA and MCGA display modes, ATTR% is
  2057.             the colour value for each pixel in the blanked lines.
  2058.  
  2059.             Scrolling sideways in graphics modes, using this routine,
  2060.             does not provide sufficiently fine movement for animation
  2061.             effects, but see the CGASCROLL and MCGASCROLL procedures
  2062.             (above) for a more precise alternative.
  2063.  
  2064.  
  2065. SECURE
  2066.  
  2067. Toggles bit zero of the specified file's directory entry, making it either
  2068. Read-only or Read/Write.
  2069.  
  2070. DECLARE SUB Secure (BYVAL Switch%, FileSpec$)
  2071.  
  2072. If SWITCH% = 1 the file is made Read-only (regardless of whether it can be
  2073. currently written to or not), any other value makes the file Read/Write.
  2074. FILESPEC is the name of the file to be hidden or unhidden. It can include
  2075. a drive letter and directory path but must be an explicit pathname,
  2076. wildcard characters are not allowed.
  2077.  
  2078.  
  2079. SERIALPORTS
  2080.  
  2081. This function checks how many serial ports are available, it does not
  2082. check to see if devices are connected to any of them.
  2083.  
  2084. No calling parameters are required.
  2085.  
  2086. DECLARE FUNCTION SerialPorts% ()
  2087.  
  2088.  
  2089. SHARE
  2090.  
  2091. Toggles bit seven of the specified file's directory entry, making it
  2092. either Shareable or Non-shareable. This routine will only work when the
  2093. program which calls it is running under a Novell Network.
  2094.  
  2095. DECLARE SUB Share (BYVAL Switch%, FileSpec$)
  2096.  
  2097. If SWITCH% = 1 the file is made Shareable (regardless of whether it can be
  2098. currently used by other programs or not), any other value makes the file
  2099. Non-shareable. FILESPEC is the name of the file to be shared. It can
  2100. include a drive letter and directory path but must be an explicit
  2101. pathname, wildcard characters are not allowed.
  2102.  
  2103.  
  2104. SHUTUP
  2105.  
  2106. Closes the last window opened by the POPUP window procedure (see above)
  2107. and restores the contents of the screen below it.
  2108.  
  2109. DECLARE SUB ShutUp (BYVAL Speed%)
  2110.  
  2111. The Speed% parameter is a delay in milliseconds. If greater than zero
  2112. it produces the effect of imploding the storage buffer contents onto the
  2113. screen, making the window appear to vanish into a point source.
  2114.  
  2115.  
  2116. SIZEOF
  2117.  
  2118. This function will return the size of the file specified in bytes, or, if
  2119. more than one match is found, the total size of all such files. If a size
  2120. of zero is returned, no matching file exists (at least not in the
  2121. directory specified).
  2122.  
  2123. DECLARE FUNCTION SizeOf& (FileSpec$)
  2124.  
  2125. The filename can include a directory path and may be ambiguous, using the
  2126. wildcard characters '*' and '?'.
  2127.  
  2128.  
  2129. SOUNDEX
  2130.  
  2131. Gets the phonetic equivalent of a string. This function returns a long
  2132. integer which represents the 'sound' of a string of text using the SOUNDEX
  2133. phonetic conversion algorithm. It can be used in 'fuzzy' searches, for
  2134. example, to scan a database for an individual when you are not sure of the
  2135. exact spelling of their surname. When searching for SMITH, for instance,
  2136. SOUNDEX would also match SMYTH and SMYTHE.
  2137.  
  2138. DECLARE FUNCTION Soundex& (Text$)
  2139.  
  2140. Note that the initial letter of the search string must exactly match the
  2141. initial letter of the target. GAMMELL and CAMMEL will return different
  2142. values when passed to SOUNDEX. Note also that the function will only
  2143. convert the first word of the string, translation stops at the first
  2144. blank space.
  2145.  
  2146.  
  2147. SPOOLER
  2148.  
  2149. Gets the installed state of the DOS print spooler, PRINT.COM, so that a
  2150. program can check if it is safe to submit files to the print queue.
  2151.  
  2152. No calling parameters are required.
  2153.  
  2154. DECLARE FUNCTION Spooler% ()
  2155.  
  2156. Returns:    -1  if spooler is installed
  2157.              0  if spooler is not installed
  2158.  
  2159.  
  2160. SPOOLDELETE
  2161.  
  2162. Deletes one or more files from the current print queue.
  2163.  
  2164. FileSpec$ should include the full pathname of the file to be deleted from
  2165. the print queue. It can be ambiguous, using the DOS wildcard characters
  2166. '*' and '?', allowing you to cancel the processing of a range of files
  2167. with a single command.
  2168.  
  2169. DECLARE SUB SpoolDelete (FileSpec$)
  2170.  
  2171. Note:       This function will only work if PRINT.COM, the DOS print
  2172.             spooler has been installed. You can use the SPOOLER
  2173.             function (see above) to check if PRINT.COM is available.
  2174.  
  2175.  
  2176. SPOOLFLUSH
  2177.  
  2178. Deletes all files from the current print queue and terminates output to
  2179. the printer.
  2180.  
  2181. No calling parameters are required.
  2182.  
  2183. DECLARE SUB SpoolFlush ()
  2184.  
  2185. Note:       This function will only work if PRINT.COM, the DOS print
  2186.             spooler has been installed. You can use the SPOOLER
  2187.             function (see above) to check if PRINT.COM is available.
  2188.  
  2189.  
  2190. SPOOLLIST
  2191.  
  2192. Returns the pathname of a file in the current print queue.
  2193.  
  2194. SPOOLLIST can only be used while printing is suspended after a call to the
  2195. SPOOLSUSPEND function (see below) has been made.
  2196.  
  2197. Buffer$ must be preset to a length of at least 64 bytes for the routine to
  2198. work, although you do not have to fill it with spaces first.  When called,
  2199. immediately after printing has been suspended, SPOOLLIST will return, in
  2200. Buffer$, the pathname of the first file in the spooler print queue.
  2201.  
  2202. Further calls will return the names of subsequent files in the queue until
  2203. a string of blank spaces indicates that all entries have been read.
  2204.  
  2205. DECLARE SUB SpoolList (Buffer$)
  2206.  
  2207. The following example demonstrates how SPOOLLIST, SPOOLSUSPEND and
  2208. SPOOLRESTART can be used in a QuickBASIC program.
  2209.  
  2210.     CONST FALSE = 0, TRUE = NOT FALSE
  2211.  
  2212.     Buffer$ = STRING$(64, "*")
  2213.  
  2214.     Status% = SpoolSuspend%
  2215.     PRINT "Spooler suspended, status is"; Status%
  2216.     PRINT "Files in print queue are ...": PRINT
  2217.     Done% = FALSE: Number% = 1
  2218.     DO
  2219.         SpoolList Buffer$
  2220.         IF Buffer$ = SPACE$(64) THEN
  2221.            Done% = TRUE
  2222.         ELSE
  2223.            PRINT Number%, Buffer$
  2224.            Number% = Number% + 1
  2225.        END IF
  2226.     LOOP UNTIL Done%
  2227.     CALL SpoolReStart
  2228. END
  2229.  
  2230. Use SPOOLRESTART (see below) to resume printing after it has been
  2231. suspended for a listing of the queue contents to be made.
  2232.  
  2233. Note:       This function will only work if PRINT.COM, the DOS print
  2234.             spooler has been installed. You can use the SPOOLER
  2235.             function (see above) to check if PRINT.COM is available.
  2236.  
  2237.  
  2238. SPOOLRESTART
  2239.  
  2240. Re-enables output of spooled files to the printer after it has been
  2241. suspended for a status check or for the queue contents to be listed.
  2242.  
  2243. No calling parameters are required.
  2244.  
  2245. DECLARE SUB SpoolReStart ()
  2246.  
  2247. Note:       This function will only work if PRINT.COM, the DOS print
  2248.             spooler has been installed. You can use the SPOOLER
  2249.             function (see above) to check if PRINT.COM is available.
  2250.  
  2251.  
  2252. SPOOLSUBMIT
  2253.  
  2254. Submits a file for processing by the DOS print spooler. 
  2255.  
  2256. FileSpec$ should contain the full pathname of the file to be printed and
  2257. should be no longer than 64 characters. Wildcard characters are not
  2258. allowed. If found, the file will be added to the end of the current print
  2259. queue.
  2260.  
  2261. DECLARE SUB SpoolSubmit (FileSpec$)
  2262.  
  2263. Note:       This function will only work if PRINT.COM, the DOS print
  2264.             spooler has been installed. You can use the SPOOLER
  2265.             function (see above) to check if PRINT.COM is available.
  2266.  
  2267.  
  2268. SPOOLSUSPEND
  2269.  
  2270. Suspends output from the DOS print spooler and reports if an error has
  2271. been encountered. Printing is suspended until you use the SPOOLRESTART
  2272. procedure (see above) to resume output. 
  2273.  
  2274. No calling parameters are required.
  2275.  
  2276. DECLARE FUNCTION SpoolSuspend% ()
  2277.  
  2278. Returns:     0 = no errors
  2279.              1 = invalid function
  2280.              2 = file not found
  2281.              3 = path not found
  2282.              4 = too many open files
  2283.              5 = access denied
  2284.              8 = queue full
  2285.              9 = spooler busy
  2286.             12 = name too long
  2287.             15 = invalid drive    
  2288.  
  2289. SPOOLLIST (see above), which returns the pathnames of files in the print
  2290. queue, can only be called while the spooler is suspended.
  2291.  
  2292. Note:       This function will only work if PRINT.COM, the DOS print
  2293.             spooler has been installed. You can use the SPOOLER
  2294.             function (see above) to check if PRINT.COM is available.
  2295.  
  2296.  
  2297. STATUSLINE
  2298.  
  2299. This procedure displays the message supplied on the bottom line of the
  2300. display, prompts the user for a keypress, waits until it is received and
  2301. then returns, restoring the screen to its former state. The  ASCII value
  2302. of the keypress is returned in the variable that you assign to the
  2303. function.
  2304.  
  2305. DECLARE FUNCTION StatusLine% (Message$)
  2306.  
  2307. Note:       StatusLine will recognise if an EGA or VGA is installed and
  2308.             will correctly locate itself if the screen is in 43 or 50-
  2309.             line mode.
  2310.  
  2311.  
  2312. STRINGSCAN
  2313.  
  2314. This routine searches a variable-length string array for the string
  2315. specified, returning the element number it occupies if found.
  2316.  
  2317. DECLARE FUNCTION StringScan% (Trgt$, BYVAL Size%, BYVAL Strt%, BYVAL Addr%)
  2318.  
  2319. Arguments:  Trgt$ = target string to be searched for.
  2320.             Size% = number of array elements to be searched.
  2321.             Strt% = array element to start searching at.
  2322.             Addr% = address of start element (the VARPTR value).  
  2323.                      
  2324. See also the STRINGSORT routine (below) for a fast method of sorting a
  2325. variable-length string array.
  2326.  
  2327.  
  2328. STRINGSORT
  2329.  
  2330. This procedure can sort a string array into ascending or descending order,
  2331. very quickly indeed.
  2332.  
  2333. DECLARE SUB StringSort (BYVAL Dir%, BYVAL Size%, BYVAL Addr%)
  2334.  
  2335. Arguments:  Dir%    = sort direction (0 = ascending, 1 = descending).
  2336.             Size%   = number of elements to sort.
  2337.             Addr%   = VARPTR of element to start sorting from.
  2338.  
  2339. Note:       This routine now works perfectly with Extended QuickBASIC
  2340.             far string arrays, provided that the range of elements to
  2341.             sort are contained within a single 64K segment. If the
  2342.             array extends over more than one segment then no sorting
  2343.             will be performed at all.
  2344.  
  2345.  
  2346. ULPRINT
  2347.  
  2348. Sends the text supplied, to the printer, as a string of underlined
  2349. characters.  Output begins at the current print position and can,
  2350. optionally, append a carriage-return/linefeed to take the print head to
  2351. the beginning of a new line when finished.
  2352.  
  2353. DECLARE SUB UlPrint (BYVAL Printer%, Buffer$, BYVAL NewLine%)
  2354.  
  2355. Arguments:  Printer%    the parallel port output is to be sent to
  2356.                         (1 = LPT1:, 2 = LPT2:, etc.).
  2357.             Buffer$     the string of text to be printed.
  2358.             NewLine%    set this to a non-zero value if you want 
  2359.                         to move to a new line after printing.
  2360.  
  2361. The routine restores the previous print style or font before it returns
  2362. and does not effect subsequent output to the printer, using the QuickBASIC
  2363. LPRINT or PRINT # statements.
  2364.  
  2365. Note:       The version of this routine stored in the Toolbox
  2366.             library is for EPSON compatible printers. If you have
  2367.             an IBM graphics printer or ProPrinter, then you should
  2368.             rebuild your libraries, using either the PRINTIBM.OBJ
  2369.             or PRINTPRO.OBJ object module in place of PRINTEPS.OBJ.
  2370.  
  2371.  
  2372. VERIFY
  2373.  
  2374. This function opens a dialogue box, centered at the screen row specified,
  2375. in which is displayed a prompt supplied by the caller. The routine adds a
  2376. further Y/N prompt, and then waits for a keypress. Only <Y/N> responses
  2377. (in upper or lower case) are accepted and the value that is returned
  2378. evaluates to Boolean TRUE (-1), if a Y(es) response was entered, and
  2379. Boolean FALSE (0) if the reply was N(o). The screen is restored to its
  2380. previous state on exit from the function.
  2381.  
  2382. DECLARE FUNCTION Verify% (BYVAL Default%, BYVAL Row%, Prompt$,_
  2383.                           BYVAL Attr%, BYVAL Mouse%)
  2384.  
  2385. DEFAULT%    Specifies the radio button to be highlighted as the default
  2386.             response on entry into the function. Pressing <Return> or
  2387.             clicking the left mouse button without moving the pointer
  2388.             will produce the specified response. If DEFAULT% is set to
  2389.             one the YES button is highlighted. Any other value highlights
  2390.             the NO button. 
  2391.  
  2392. ROW%        The top row of the dialogue box when it is displayed. The
  2393.             box is automatically centered within this row, which may be
  2394.             adjusted so that it remains within the screen boundaries.
  2395.  
  2396. PROMPT$     A string of text comprising the message to be displayed. It
  2397.             must be no longer than 40 characters otherwise it will be
  2398.             truncated to fit inside the display panel.
  2399.  
  2400. ATTR%       The display attribute or colour to be given to the dialogue box.
  2401.             If an argument of zero is supplied, the box is displayed with
  2402.             bright white text on a blue background (colour monitors) or in
  2403.             reverse video (monochrome monitors).
  2404.  
  2405. MOUSE%      should be set to TRUE (-1) or FALSE (0) to indicate if a mouse
  2406.             is installed and can be used to respond.    
  2407.  
  2408. Notes:      The user can respond, either by pressing the <Y> or <N> keys
  2409.             or by using <TAB> to highlight the appropriate radio button
  2410.             and then pressing <RETURN>. 
  2411.  
  2412. Mouse support has now been added, enabling the operator to respond by
  2413. clicking the mouse cursor on the appropriate radio button.
  2414.  
  2415.  
  2416. VGADIM
  2417.  
  2418. Allows a program running on a computer fitted with VGA to dim or brighten
  2419. the display intensity.
  2420.  
  2421. DECLARE SUB VGADim (BYVAL Intensity%)
  2422.  
  2423. Intensity% is a number in the range -63 to +63 which sets the brightness
  2424. of the screen relative to the default value (zero).
  2425.  
  2426.  
  2427. VGALOAD
  2428.  
  2429. Loads EGA, VGA and MCGA screens into video memory from disk. This is an
  2430. alternative to the QuickBASIC BLOAD statement which cannot be used with
  2431. the higher-resolution graphics displays provided by SCREEN modes 7 to 13.
  2432.  
  2433. DECLARE SUB VGALoad (File$)
  2434.  
  2435. FILE$ must be a legal DOS filename, including extension, drive letter and
  2436. directory path where appropriate.
  2437.  
  2438. Note:       The screen image must have been previously written to a disk
  2439.             file using the VGASAVE procedure (see below) and should have
  2440.             the same resolution as that provided by the current SCREEN.
  2441.  
  2442.  
  2443. VGAPAN
  2444.  
  2445. Sets the display window co-ordinates for EGA, VGA and MCGA screens.
  2446.  
  2447. This procedure sets the origins of display window within the video display
  2448. buffer used by the EGA, VGA and MCGA adaptors.  Normally this is at the
  2449. top left-hand corner of the graphics image, but by changing co-ordinates
  2450. you can pan the display through video memory, to create some interesting
  2451. animation effects.
  2452.  
  2453. DECLARE SUB VGAPan (BYVAL X%, BYVAL Y%)
  2454.  
  2455. Example program
  2456.  
  2457. ' OUTPAN.BAS - pans the virtual screen window on EGA and VGA
  2458. '              display adaptors.
  2459. '
  2460. '   Author:    Christy Gemmell
  2461. '   For:       Assembly-Language ToolBox for QuickBASIC
  2462. '   Date:      11/12/89
  2463. '
  2464.     DECLARE FUNCTION KeyIn% ()
  2465.     DECLARE SUB VGAPan (BYVAL X%, BYVAL Y%)
  2466.  
  2467.     CONST FALSE = 0, TRUE = NOT FALSE
  2468.  
  2469.     SCREEN 9: LINE (0, 0)-(639, 349), 9, BF
  2470.     VIEW SCREEN (40, 25)-(600, 325), 0, 15
  2471.     CIRCLE (319, 174), 150, 14: PAINT (319, 174), 14, 14
  2472.  
  2473.     X% = 0: Y% = 0
  2474.  
  2475.     DO
  2476.         KeyPress% = KeyIn%: Pan% = TRUE
  2477.         SELECT CASE KeyPress%
  2478.             CASE -75
  2479.                 IF X% > 0 THEN X% = X% - 1
  2480.             CASE -77
  2481.                 IF X% < 79 THEN X% = X% + 1
  2482.             CASE -72
  2483.                 IF Y% > 0 THEN Y% = Y% - 1
  2484.             CASE -80
  2485.                 IF Y% < 22 THEN Y% = Y% + 1
  2486.             CASE ELSE
  2487.                 Pan% = FALSE
  2488.         END SELECT
  2489.         IF Pan% THEN VGAPan X%, Y% * 5
  2490.     LOOP UNTIL KeyPress% = 27
  2491. END
  2492.  
  2493.  
  2494. VGASAVE
  2495.  
  2496. Saves EGA, VGA and MCGA screens from video memory to disk. 
  2497.  
  2498. The normal QuickBASIC BLOAD and BSAVE statements only work properly with
  2499. text and CGA graphics screens. This routine allows you to do the same
  2500. with higher-resolution graphic displays in SCREEN modes 7 to 13.
  2501.  
  2502. DECLARE SUB VGASave (File$)
  2503.  
  2504. FILE$ must be a legal DOS filename, including the extension, drive letter
  2505. and directory path where appropriate.
  2506.  
  2507. A companion procedure, VGALOAD (see above) is provided to allow you to
  2508. retrieve the graphics image from disk, and restore it to the screen.
  2509.  
  2510. Example program
  2511.  
  2512. ' VGAFILE.BAS  saves and loads a high-resolution graphics image
  2513. '
  2514. '   Author:     Christy Gemmell
  2515. '   For:        Assembly-Language ToolBox for QuickBASIC
  2516. '   Date:       11/12/89
  2517. '
  2518. '   Graphics converted from Microsoft Extended Color BASIC
  2519. '
  2520.     DECLARE SUB VGALoad (File$)
  2521.     DECLARE SUB VGASave (File$)
  2522.  
  2523.     ScreenMode% = 12              ' Try other modes as well
  2524.  
  2525.     SELECT CASE ScreenMode%
  2526.         CASE 7, 13
  2527.              xMax% = 319: yMax% = 199
  2528.         CASE 8
  2529.              xMax% = 639: yMax% = 199
  2530.         CASE 9, 10
  2531.              xMax% = 639: yMax% = 349
  2532.         CASE 11, 12
  2533.              xMax% = 639: yMax% = 479
  2534.         CASE ELSE
  2535.     END SELECT
  2536.  
  2537.     SCREEN ScreenMode%: KEY OFF
  2538.     LINE (0, 0)-(xMax%, yMax%), 6, BF
  2539.     VIEW (32, 4)-(xMax% - 32, yMax% - 4), 0, 5
  2540.     WINDOW SCREEN (0, 0)-(255, 191)
  2541.     FOR I% = 1 TO 40
  2542.         READ A%, B%, C%, D%: LINE (A%, B%)-(C%, D%), 1
  2543.     NEXT I%
  2544.     PAINT (56, 20), 1, 1: PAINT (136, 64), 1, 1
  2545.     PAINT (120, 80), 1, 1: PAINT (192, 88), 14, 1
  2546.     PAINT (76, 48), 14, 1: PAINT (124, 60), 14, 1
  2547.     PAINT (68, 12), 2, 1: PAINT (80, 84), 2, 1
  2548.     PAINT (92, 128), 2, 1: PAINT (36, 156), 12, 1
  2549.     PAINT (36, 168), 1, 1: PAINT (84, 178), 14, 1
  2550.     PAINT (88, 118), 12, 1: PAINT (144, 86), 12, 1
  2551.     VGASave "ESCHER.IMG": SLEEP 1: CLS : SLEEP 3
  2552.     VGALoad "ESCHER.IMG": R$ = INPUT$(1)
  2553. END
  2554.  
  2555. DATA    68,4,200,76,52,12,112,44,128,52,172,76,128,52,68,84,112,44,84,60
  2556. DATA    128,68,99,84,68,36,97,52,128,68,154,84,128,68,128,116,128,52,128
  2557. DATA    68,68,4,52,12,172,76,142,90,142,76,142,108,142,108,200,76,200,76
  2558. DATA    200,92,200,92,68,164,128,116,84,140,52,12,52,154,52,154,68,164
  2559. DATA    68,164,68,100,68,36,68,84,84,45,84,76,84,109,84,140,68,100,97,116
  2560. DATA    84,124,112,108,68,84,128,116,84,76,112,92,112,77,112,108,84,119
  2561. DATA    92,114,142,86,151,82,180,66,186,62,186,62,236,90,236,90,68,184
  2562. DATA    68,184,16,154,16,154,52,133,16,154,16,160,16,160,68,190,68,190
  2563. DATA    68,184,68,190,236,96,236,96,236,90
  2564.  
  2565.  
  2566. VGATEXT
  2567.  
  2568. Writes characters to the screen in EGA and VGA graphics modes.
  2569.  
  2570. DECLARE SUB VgaText (BYVAL xLoc%, BYVAL yLoc%, Text$,_
  2571.                      BYVAL Attr%, BYVAL Scale%)
  2572.  
  2573. This routine provides a convenient way of displaying text in any of the
  2574. EGA and VGA graphics modes (SCREENs 7-12) without having to bother about
  2575. loading external font files. It uses the standard character definition
  2576. tables built into your display adaptor, but allows you to scale them up to
  2577. eight times normal size and to specify any combination of foreground and
  2578. background colours supported by the current video mode.
  2579.  
  2580. XLOC%       The horizontal co-ordinate of the top left hand pixel
  2581.             from which the text will begin
  2582.  
  2583. YLOC%       The vertical co-ordinate of the top left hand pixel
  2584.             from which the text will begin
  2585.  
  2586. TEXT$       The string of text to be displayed (up to 63 characters).
  2587.  
  2588. ATTR%       The colour (or display attribute in monochrome modes) to
  2589.             be given to the text. This is calculated by the formula:
  2590.  
  2591.             Colour% = (Background% * 256) + Foreground%
  2592.  
  2593.             Foreground and Background values are in the ranges used
  2594.             by the current video mode (eg. 0 - 15 for SCREEN 9). The
  2595.             actual colours displayed depend upon your current PALETTE
  2596.             settings.
  2597.  
  2598.             Note:   supplying a value of -1 for background prevents
  2599.                     background pixels from being changed at all. This
  2600.                     allows text to be blended more naturally into a
  2601.                     complex graphics display.
  2602.  
  2603. SCALE%      The character size of the text to be displayed. This ranges
  2604.             from 1 to 8, where 1 is standard 80-column text (40-column
  2605.             in SCREEN 7) and 8 multiplies the character size by eight
  2606.             on both the horizontal and vertical axes.
  2607.  
  2608. VGATEXT can handle both byte-aligned and non byte-aligned characters. The
  2609. x, y co-ordinates you supply do not need to correspond to a row, column
  2610. character cell in SCREEN 0, the alphanumeric mode. The complete extended
  2611. ASCII character set is supported, including foreign symbols and
  2612. box-drawing characters.
  2613.  
  2614. Since VGATEXT does not support clipping, to ensure a clean display you
  2615. must ensure that the text to be output fits within the current screen
  2616. boundaries.
  2617.  
  2618. See also CGATEXT for displaying characters in SCREEN 1 and MCGATEXT for
  2619. displaying characters in SCREEN 13.
  2620.  
  2621.  
  2622. WEEKDAY
  2623.  
  2624. This function is used to determine the day of the week for a given date.
  2625. It does this by temporarily resetting the system date to the one supplied,
  2626. reading the day from DOS, and then restoring the old date. The weekday is
  2627. returned as a number between 0 and 6, signifying Sunday through Saturday.
  2628.  
  2629. DECLARE FUNCTION WeekDay% (BYVAL Day%, BYVAL Month%, BYVAL Year%)
  2630.  
  2631.  
  2632. ──────────────────────────────────────────────────────────────────────
  2633.  
  2634. EXTRA ROUTINES FOR QB4
  2635.  
  2636. The following functions and procedures are only included in the version of
  2637. the Toolbox intended for QuickBASIC 4.x and BASIC 6. They are omitted from
  2638. the later version because the Extended QuickBASIC language provided with
  2639. the BASIC 7 Professional Development System includes new statements and
  2640. functions that render them unneccessary. Well they say that imitation IS
  2641. the sincerest form of flattery!
  2642.  
  2643.  
  2644. FINDFIRST
  2645.  
  2646. This routine sets the Disk Transfer Address to point to a local buffer and
  2647. then attempts to find a match for the file specified in WildCard$. If one
  2648. or more matches are found, the filename of the first matching file (minus
  2649. directory path), is stuffed into the second string argument. If no match
  2650. is found, this string is filled with blank spaces.
  2651.  
  2652. DECLARE SUB FindFirst (Attr%, WildCard$, Match$)
  2653.  
  2654. WildCard$ can contain an ambiguous filename, using the wildcard characters
  2655. * and ?, in which case FINDFIRST will only find the first matching file.
  2656. To obtain the names of any subsequent matches, use the FINDNEXT function
  2657. (see below).
  2658.  
  2659. Match$ must be at least twelve characters long to hold the returning
  2660. filename and extension. You do not need to clear the string first as the
  2661. function does that for you, automatically.
  2662.  
  2663. Normally, only visible files with full read\write access are found, but
  2664. you can extend this to search for hidden, read-only or system files as
  2665. well by setting the Attr% parameter to the appropriate attribute value.
  2666.  
  2667.    Attr% = 0   Visible read\write
  2668.            1   Read-only files
  2669.            2   Hidden files
  2670.            4   System files
  2671.  
  2672. Do not use the SIZEOF function while searching for files with FINDFIRST
  2673. and FINDNEXT. Since both routines relocate the DOS Disk Transfer Address
  2674. during operation, this may lead to a conflict which will cause your
  2675. program to lose track of one or more open files. You should, in any case,
  2676. always use the RESETDTA routine to restore the Disk Transfer Address after
  2677. FINDFIRST/FINDNEXT is completed.
  2678.  
  2679. The DIR$ function which Microsoft have added to Extended QuickBASIC (QBX)
  2680. provides a built-in FINDFIRST/FINDNEXT service which makes the Toolbox
  2681. routines redundant. They are, therefore, omitted from the BASIC 7 version.
  2682.  
  2683.  
  2684. FINDNEXT
  2685.  
  2686. Finds successive matches of an ambiguous filename after a previously
  2687. successful call to FINDFIRST (see above). You can call it repeatedly
  2688. until a blank string is returned in Match$, in which case there are
  2689. no more files to be found.
  2690.  
  2691. DECLARE SUB FindNext (Match$)
  2692.  
  2693. Match$ must be at least twelve characters long to hold the returning
  2694. filename and extension. It does not have to be cleared first, since the
  2695. routine does this for you, automatically.
  2696.  
  2697. Do not make use the SIZEOF function while searching for files with
  2698. FINDFIRST and FINDNEXT. Since both routines relocate the DOS Disk Transfer
  2699. Address during operation, this may lead to a conflict which will cause
  2700. your program to lose track of one or more open files. You should, in any
  2701. case, always use the RESETDTA routine to restore the Disk Transfer Address
  2702. after FINDFIRST/FINDNEXT is completed.
  2703.  
  2704. The DIR$ function which Microsoft have added to Extended QuickBASIC (QBX)
  2705. provides a built-in FINDFIRST/FINDNEXT service which makes the Toolbox
  2706. routines redundant. They are, therefore, omitted from the BASIC 7 version.
  2707.  
  2708.  
  2709. GETDIR
  2710.  
  2711. This procedure writes the pathname of the currently logged directory into
  2712. the string supplied by the caller. The user can specify what drive to
  2713. return the directory for, or default to the current drive.
  2714.  
  2715. DECLARE SUB GetDir (Drive%, Path$)
  2716.  
  2717. This routine expects two arguments to be passed to it. The first is an
  2718. integer which specifies the drive to look at :
  2719.  
  2720. 0 = default drive, 1 = drive A:, 2 = drive B:, etc.
  2721.  
  2722. the second argument is a string which will hold the path of the directory
  2723. returned by DOS. The string must be at least 64 bytes long to hold the
  2724. information. If it were not, the function might overwrite other variables
  2725. in the program data space, with unpredictable results. The returned path-
  2726. name does not include the drive identifier or a leading '\' and is
  2727. terminated by a null (0) byte. if the current directory is the root
  2728. directory, therefore, the first byte of the string will be an ASCII zero,
  2729. not a null string.
  2730.  
  2731. The CURDIR$ function which Microsoft have added to Extended QuickBASIC
  2732. (QBX) allows you to obtain the current directory path and drive, making
  2733. GETDIR redundant. It is, therefore, omitted from the BASIC 7 version of
  2734. the Assembly Language Toolbox.
  2735.  
  2736.  
  2737. GETDRIVE
  2738.  
  2739. This function returns the number of the currently-logged drive.
  2740.  
  2741. No calling parameters are required.
  2742.  
  2743. DECLARE FUNCTION GetDrive% ()
  2744.  
  2745. Values returned are in the series 0 = A:, 1 = B:, 2 = C:, etc.
  2746.  
  2747. The CURDIR$ function which Microsoft have added to Extended QuickBASIC
  2748. (QBX) allows you to obtain the current directory path and drive, making
  2749. GETDRIVE redundant. It is, therefore, omitted from the BASIC 7 version of
  2750. the Assembly Language Toolbox.
  2751.  
  2752.  
  2753. RESETDTA
  2754.  
  2755. This procedure must always be called by your program after the FINDFIRST
  2756. and FINDNEXT functions have been used. It restores the Disk Transfer
  2757. Address to its default value originally set by QuickBASIC.
  2758.  
  2759. No calling parameters are required.
  2760.  
  2761. DECLARE SUB ReSetDTA ()
  2762.  
  2763.  
  2764. SETDRIVE
  2765.  
  2766. This function changes the currently-logged drive to the one specified by
  2767. the calling program (0 = A:, 1 = B:, etc.).
  2768.  
  2769. DECLARE SUB SetDrive (Drive%)
  2770.  
  2771. Since BASIC 7 has now introduced the CHDRIVE statement which performs the
  2772. same task, SETDRIVE is only supported in the version of the Toolbox
  2773. supplied to QuickBASIC 4 users.
  2774.  
  2775.  
  2776. ──────────────────────────────────────────────────────────────────────
  2777.  
  2778. ASSEMBLY-LANGUAGE TOOLBOX INTERNAL FUNCTIONS
  2779.  
  2780. The following functions and procedures are used internally by Toolbox
  2781. routines. Assembly-Language programmers may also call them when adding
  2782. routines of their own, provided the appropriate object modules are linked
  2783. to their program at runtime.
  2784.  
  2785.  
  2786. FLAGS
  2787.  
  2788. Sets or gets the current status of individual flags in the Intra-
  2789. Application Communications area (IAC), a 16-byte block of RAM reserved, by
  2790. DOS, for signalling between applications programs.
  2791.  
  2792. Three parameters must be passed on the stack, they are:
  2793.  
  2794.         1)  Switch%     0 = get flag,   1 = set flag
  2795.         2)  Flag%       the offset into the IAC flag table (0 to 15)
  2796.         3)  Setting%    the value to be set into the specified byte
  2797.                         of the flag table (if Switch% = 1).
  2798.  
  2799. This example code fragment sets letter 'A' (ASCII 65) into flag 8 (byte 9)
  2800. of the IAC area.
  2801.  
  2802.             .model  medium              ; Required for QuickBASIC
  2803.  
  2804.             extrn   Flags: far          ; Public name of called routine
  2805.  
  2806.             .code                       ; Define code segment
  2807.  
  2808.             mov     ax,1                ; Set a flag byte
  2809.             push    ax                  ; Pass it on the stack
  2810.             mov     ax,8                ; Flag number 8
  2811.             push    ax                  ; Pass it on the stack
  2812.             mov     ax,'A'              ; Value to set
  2813.             push    ax                  ; Pass it on the stack
  2814.             call    Flags               ; Call the function
  2815.  
  2816. You must still push three parameters onto the stack even if you are only
  2817. reading a flag setting. In this case the third argument will be ignored.
  2818.  
  2819. The setting of the specified IAC flag is returned in the lower byte of the
  2820. AX register (AL). All other registers are preserved.
  2821.  
  2822.  
  2823. GETVERSION
  2824.  
  2825. This function checks the version of DOS under which the host computer is
  2826. currently running.
  2827.  
  2828.             extrn   GetVersion: far
  2829.  
  2830. The following register values may be returned:
  2831.  
  2832.     AL      = Major Version       (MS-DOS 3.2 = 3, etc.)
  2833.     AH      = Minor Version       (MS-DOS 3.2 = 20, etc.) 
  2834.     BH      = OEM version number  (0 = IBM PC-DOS)
  2835.     BL:CX   = 24-bit OEM serial number.
  2836.                             
  2837. GETVERSION can be called directly from QuickBASIC, in which case only the
  2838. Major and Minor version numbers returned in AX are available.
  2839.  
  2840.  
  2841. HIDECURSOR
  2842.  
  2843. Makes the cursor invisible. No parameters are required or returned.
  2844.  
  2845.             extrn   HideCursor: far
  2846.  
  2847. This method ORs the byte value of the cursor start line with 32 (20 Hex)
  2848. which, on all standard video adaptors, turns off the cursor while
  2849. preserving its display characteristics. You can use the SHOWCURSOR
  2850. routine (see below) to restore the cursor to its previous state.
  2851.  
  2852. Note:       HIDECURSOR can be called directly from QuickBASIC but, since
  2853.             the LOCATE statement provides an alternative means of turning
  2854.             off the cursor, it is not necessary.
  2855.  
  2856.  
  2857. SCREENADDRESS
  2858.  
  2859. Calculate screen address from a pair of row/column co-ordinates.
  2860.  
  2861.             extrn   ScreenAddress: far
  2862.  
  2863. Given the row/column column co-ordinate of a character on the screen, this
  2864. function returns the segment:offset address of that character in video
  2865. memory. The address is correctly adjusted to the start of the the
  2866. currently active display page, but no check is made to ensure that the
  2867. co-ordinates supplied are within the actual screen bounds.
  2868.  
  2869. Input:      AL      = Row co-ordinate of character (0 = row 1).
  2870.             AH      = Column co-ordinate of character (0 = column 1).
  2871.  
  2872. Output:     ES:DI==>  Address in video display buffer of the
  2873.                       character cell specified.
  2874.             DX      = CRT status register port address.
  2875.  
  2876. It is assumed that a previous call has been made to the VIDEOTYPE function
  2877. (see below), to determine the screen width, the port address of the CRT
  2878. status register and the correct video display segment. 
  2879.  
  2880.  
  2881. SCREENCOPY
  2882.  
  2883. Copy a character and attribute from the video display to a buffer at the
  2884. address specified.
  2885.  
  2886.             extrn   ScreenCopy: far
  2887.  
  2888. If the 'snow prevention' flag is set, this routine waits until the
  2889. beginning of the next CRT horizontal retrace period before reading data
  2890. from the display. This is necessary only on machines fitted with a Colour
  2891. Graphics Adaptor (CGA) which may suffer from glitches or screen snow if
  2892. data is copied from the screen while the video buffer is being refreshed.
  2893.  
  2894. Input:      DS:SI==>    Address of the screen location from which
  2895.                         the data is to be copied. 
  2896.             ES:DI==>    Address of the buffer into which the data
  2897.                         is to be copied.
  2898.             DX =        Port address of CRT status register.
  2899.  
  2900. Output:     SI and DI   Updated to point to next buffer locations.
  2901.             AX          destroyed.
  2902.  
  2903. It is assumed that a previous call has been made to the VIDEOTYPE function
  2904. (see below), to determine the screen width, the port address of the CRT
  2905. status register and the correct video display segment. VIDEOTYPE also sets
  2906. an internal 'snow-prevention' flag if the host machine has a CGA display
  2907. adaptor installed. This activates a routine which synchronises direct
  2908. video reads and writes to the CRT vertical retrace period, preventing
  2909. interference on the display.
  2910.  
  2911.  
  2912. SCREENREAD
  2913.  
  2914. Read a character and attribute from the display.
  2915.  
  2916.             extrn   ScreenRead: far
  2917.  
  2918. This procedure is similar to SCREENCOPY (see above), except that the word
  2919. is simply loaded into AX instead of being copied into a buffer.
  2920.  
  2921. Input:      DS:SI==>    address, in the video display buffer, from
  2922.                         where the data is to be read
  2923.             DX =        port address of the CRT status register.
  2924.  
  2925. Output:     AL =        character at the specified address
  2926.             AH =        display attribute given to character
  2927.             DI          updated to point to the next word address
  2928.  
  2929. It is assumed that a previous call has been made to the VIDEOTYPE function
  2930. (see below), to determine the screen width, the port address of the CRT
  2931. status register and the correct video display segment. VIDEOTYPE also sets
  2932. an internal 'snow-prevention' flag if the host machine has a CGA display
  2933. adaptor installed. This activates a routine which synchronises direct
  2934. video reads and writes to the CRT vertical retrace period, preventing
  2935. interference on the display.
  2936.  
  2937.  
  2938. SCREENWRITE
  2939.  
  2940. Output a character and attribute to the video display.
  2941.  
  2942.             extrn   ScreenWrite: far
  2943.  
  2944. If the 'snow prevention' flag is set, this routine waits until the
  2945. beginning of the next CRT horizontal retrace period before writing data to
  2946. the display. This is necessary only on machines fitted with a Colour
  2947. Graphics Adaptor (CGA) which may suffer from glitches or screen snow if
  2948. data is written to the screen while the video buffer is being refreshed.
  2949.  
  2950. Input:      ES:DI==>    Address in the video display buffer where
  2951.                         the data is to be written. 
  2952.             DX =        Port address of CRT status register.
  2953.             AL =        Character to output.
  2954.             AH =        Display attribute to set
  2955.  
  2956. Output:     DI          Updated to point to next output address.
  2957.  
  2958. It is assumed that a previous call has been made to the VIDEOTYPE function
  2959. (see below), to determine the screen width, the port address of the CRT
  2960. status register and the correct video display segment. VIDEOTYPE also sets
  2961. an internal 'snow-prevention' flag if the host machine has a CGA display
  2962. adaptor installed. This activates a routine which synchronises direct
  2963. video reads and writes to the CRT vertical retrace period, preventing
  2964. interference on the display.
  2965.  
  2966.  
  2967. SHOWCURSOR
  2968.  
  2969. Makes the cursor visible. No parameters are required or returned.
  2970.  
  2971.             extrn   ShowCursor: far
  2972.  
  2973. This method ANDs the byte value of the cursor start line with 31 (1F Hex)
  2974. which, restores the cursor after being made invisible by the HIDECURSOR
  2975. routine (see above).
  2976.  
  2977. Note:       SHOWCURSOR can be called directly from QuickBASIC but, since
  2978.             the LOCATE statement provides an alternative means of turning
  2979.             the cursor on and off, it is not needed in high-level code.
  2980.  
  2981.  
  2982. VIDEO
  2983.  
  2984. Video equipment check. This function returns information about the active
  2985. display adaptor installed in the host system.
  2986.  
  2987.             extrn   Video: far
  2988.  
  2989. No input parameters are required, on return AX should be examined for the
  2990. following values:
  2991.     
  2992.         AL = type of video adaptor installed
  2993.  
  2994.              1 = MDA   - Monochrome Display Adaptor
  2995.              2 = CGA   - Colour Graphics Adaptor
  2996.              3 = HGC   - Hercules Graphics Card
  2997.              4 = HGC+  - Hercules Graphics Card Plus
  2998.              5 = HIC   - Hercules InColour Card
  2999.              6 = EGA   - Extended Graphics Adaptor
  3000.              7 = PGA   - Professional Graphics Adaptor (IBM PS/2)
  3001.              8 = VGA   - Video Graphics Array
  3002.              9 = MCGA  - MultiColour Graphics Adaptor  (IBM PS/2)
  3003.  
  3004.         AH  (bits 0-6) = size of display memory in 16K blocks
  3005.                          (0 = <16K, 1 = 16K, 2 = 32K, etc.)
  3006.             (bit 7)    = type of display monitor in use
  3007.                          (0 = colour, 1 = monochrome) 
  3008.  
  3009.  
  3010. VIDEOTYPE
  3011.  
  3012. Collects information about the current video display and sets various
  3013. internal flags.
  3014.  
  3015.             extrn   VideoType: far
  3016.  
  3017. The correct video display segment and CRT status port addresses are
  3018. determined for the current system and, if necessary, the internal 'snow'
  3019. prevention flag is set.
  3020.  
  3021. Input:      nothing
  3022.  
  3023. Output:     AL =    Current display mode
  3024.             AH =    Screen width in columns
  3025.             BL =    Screen height in rows
  3026.             BH =    Active display page
  3027.  
  3028. You should make a preliminary call to this function before using any of
  3029. the other internal routines which directly access video memory.
  3030.  
  3031.  
  3032. WRITEBYTE
  3033.  
  3034. Output a byte of data to video memory.
  3035.  
  3036.             extrn   WriteByte: far
  3037.  
  3038. This procedure is similar to ScreenWrite, above, except that only a single
  3039. byte is written. It is used by the BackFill routine to reset the display
  3040. attribute of a character, without changing the character itself.
  3041.  
  3042. Input:      ES:DI==>    address, in the video display buffer, where
  3043.                         the byte is to be written.
  3044.             DX =        port address of the CRT status register.
  3045.             AL =        the byte value to be written.
  3046.  
  3047. Output:     DI          updated to point to the next byte address
  3048.  
  3049. It is assumed that a previous call has been made to the VIDEOTYPE function
  3050. (see above) to determine the screen width, the port address of the CRT
  3051. status register and the correct video display segment. VIDEOTYPE also sets
  3052. an internal 'snow-prevention' flag if the host machine has a CGA display
  3053. adaptor installed. This activates a routine which synchronises direct
  3054. video reads and writes to the CRT vertical retrace period, preventing
  3055. interference on the display.
  3056.  
  3057.  
  3058. ─────────────────────────────────────────────────────────────────────────
  3059.